全部产品
Search
文档中心

ApsaraVideo Live:Putar dan publikasikan audio eksternal

更新时间:Dec 18, 2025

Topik ini menjelaskan cara mencampurkan sumber audio eksternal—seperti musik latar, efek suara, atau aliran audio PCM kustom—ke dalam aliran audio SDK ARTC, sehingga Anda dapat memutar audio campuran tersebut secara lokal dan mengalirkannya ke pengguna remote di saluran.

Deskripsi fitur

SDK ARTC mendukung pencampuran audio eksternal untuk pemutaran lokal dan publikasi ke pengguna remote. Fitur ini memungkinkan Anda mengintegrasikan serta mengirimkan berbagai sumber audio, mulai dari file yang telah direkam sebelumnya dalam format seperti MP4, WAV, dan AAC hingga aliran data PCM real-time.

Kasus penggunaan

  • Pengambilan aliran file audio: Masukkan secara dinamis efek suara, musik latar, atau konten ucapan ke dalam siaran langsung. Misalnya, Anda dapat memicu suara notifikasi produk selama siaran langsung e-commerce atau memuat efek suara ambient selama siaran langsung game.

  • Pengambilan aliran PCM: Digunakan untuk layanan suara interaktif real-time. Misalnya, Anda dapat mengambil aliran audio PCM yang dihasilkan oleh output teks-ke-ucapan (TTS) dari sistem layanan pelanggan cerdas.

Kode contoh

Android: Android/ARTCExample/BasicUsage/src/main/java/com/aliyun/artc/api/basicusage/PlayAudioFiles/PlayAudioFilesActivity.java

iOS: iOS/ARTCExample/BasicUsage/PlayAudioFiles/PlayAudioFilesVC.swift

Sebelum memulai

Sebelum mengimplementasikan fitur ini, pastikan Anda memenuhi persyaratan berikut:

Putar atau publikasikan file audio

Cara kerja

Fitur ini dirancang untuk memutar atau mempublikasikan file audio selama sesi real-time dan menyediakan dua set API untuk kasus penggunaan yang berbeda:

  • API iringan: Ditujukan untuk memutar file audio yang lebih panjang, seperti musik latar atau iringan musik. Hanya satu file audio dapat diputar dalam satu waktu.

  • API efek suara: Dioptimalkan untuk memutar klip audio pendek dan transien, seperti tepuk tangan atau tawa. Beberapa efek suara dapat diputar secara bersamaan.

Catatan

Sebelum memutar atau mempublikasikan audio eksternal, Anda harus terlebih dahulu bergabung ke saluran dan mulai mempublikasikan aliran audio primary Anda. Tunggu callback onAudioPublishStateChanged untuk memastikan aliran audio Anda telah dipublikasikan.

Fitur terkait adalah sebagai berikut:

Fitur

API iringan

API efek suara

Putar, hentikan, jeda, dan lanjutkan file audio

  • startAudioAccompany

  • stopAudioAccompany

  • pauseAudioAccompany

  • resumeAudioAccompany

  • preloadAudioEffect

  • unloadAudioEffect

  • playAudioEffect

  • stopAudioEffect

  • stopAllAudioEffects

  • pauseAudioEffect

  • pauseAllAudioEffects

  • resumeAudioEffect

  • resumeAllAudioEffects

Dapatkan dan sesuaikan progres pemutaran

  • getAudioAccompanyDuration

  • getAudioAccompanyCurrentPosition

  • setAudioAccompanyPosition


Dapatkan dan sesuaikan volume pemutaran audio

  • setAudioAccompanyVolume

  • setAudioAccompanyPublishVolume

  • getAudioAccompanyPublishVolume

  • setAudioAccompanyPlayoutVolume

  • getAudioAccompanyPlayoutVolume

  • setAudioEffectPublishVolume

  • getAudioEffectPublishVolume

  • setAudioEffectPlayoutVolume

  • getAudioEffectPlayoutVolume

  • setAllAudioEffectsPublishVolume

  • setAllAudioEffectsPlayoutVolume

Laporkan status pemutaran file audio

Lokal:

  • onAudioAccompanyStateChanged

Remote:

  • onRemoteAudioAccompanyStarted

  • onRemoteAudioAccompanyFinished

Lokal:

  • onAudioEffectFinished

Dapatkan informasi file audio

  • getAudioFileInfo

  • onAudioFileInfo

Mainkan iringan

Hanya satu file iringan dapat diputar dalam satu waktu.

  1. Bergabung ke saluran dan publikasikan aliran audio. Ini diaktifkan secara default di SDK.

    Android

    // Untuk memutar sumber audio eksternal, Anda harus terlebih dahulu mempublikasikan aliran audio primary. Ini diaktifkan secara default.
    mAliRtcEngine.publishLocalAudioStream(true);

    iOS

    // Untuk memutar sumber audio eksternal, Anda harus terlebih dahulu mempublikasikan aliran audio primary. Ini diaktifkan secara default. 
    engine.publishLocalAudioStream(true)
  2. Kontrol pemutaran

Setelah bergabung ke saluran dan mempublikasikan aliran audio, panggil startAudioAccompany untuk memutar iringan. Pemanggilan yang berhasil akan memicu callback onAudioAccompanyStateChanged pada client lokal dan callback onRemoteAudioAccompanyStarted pada client remote.

Gunakan API berikut untuk mengontrol pemutaran:

  • stopAudioAccompany: Menghentikan pemutaran.

  • pauseAudioAccompany: Menjeda pemutaran.

  • resumeAudioAccompany: Melanjutkan pemutaran.

  • getAudioAccompanyDuration, getAudioAccompanyCurrentPosition, dan setAudioAccompanyPosition: Mendapatkan durasi file dan mengontrol progres pemutaran.

  • setAudioAccompanyVolume: Mengatur volume pemutaran lokal dan volume publikasi remote untuk iringan.

  • getAudioAccompanyPublishVolume dan setAudioAccompanyPublishVolume: Mendapatkan atau menyesuaikan volume pemutaran remote untuk iringan.

  • getAudioAccompanyPlayoutVolume dan setAudioAccompanyPlayoutVolume: Mendapatkan atau menyesuaikan volume pemutaran lokal untuk iringan.

Android

// Path ke file iringan audio.
private String mMixingMusicFilepath = "/assets/music.wav";

// Konfigurasikan pemutaran iringan audio.
AliRtcEngine.AliRtcAudioAccompanyConfig config = new AliRtcEngine.AliRtcAudioAccompanyConfig();
config.loopCycles = -1; // Jumlah putaran. -1 berarti putaran tak terbatas.
config.publishVolume = publishVolume; // Volume publikasi. Rentang: [0-100].
config.playoutVolume = playbackVolume; // Volume pemutaran lokal. Rentang: [0-100].
config.startPosMs = 0; // Posisi awal pemutaran dalam milidetik.
// Mulai pemutaran
mAliRtcEngine.startAudioAccompany(mMixingMusicFilepath, config);

// Jeda/Lanjutkan iringan
mAliRtcEngine.pauseAudioAccompany();
mAliRtcEngine.resumeAudioAccompany();

// Hentikan pemutaran
mAliRtcEngine.stopAudioAccompany();

// Dapatkan durasi file iringan dalam ms. Panggil metode ini setelah startAudioAccompany, jika tidak akan mengembalikan -1.
int duration = mAliRtcEngine.getAudioAccompanyDuration();
// Untuk mendapatkan durasi file tertentu, panggil getAudioFileInfo. Anda dapat memanggil ini setelah membuat engine. Hasilnya dikembalikan dalam callback onAudioFileInfo.
mAliRtcEngine.getAudioFileInfo(filePath);
@Override
public void onAudioFileInfo(AliRtcEngine.AliRtcAudioFileInfo info, AliRtcEngine.AliRtcAudioAccompanyErrorCode errorCode) {

    handler.post(() -> {
        String msg = "onAudioFileInfo.file:" + info.filePath + "duration:" + info.durationMs + "audioPlayingErrorCode=" + errorCode;
        ToastHelper.showToast(PlayAudioFilesActivity.this, msg, Toast.LENGTH_SHORT);
    });
}

// Dapatkan/Setel volume.
mAliRtcEngine.setAudioAccompanyVolume(50); // [0, 100]
int publishVolume = mAliRtcEngine.getAudioAccompanyPublishVolume();
mAliRtcEngine.setAudioAccompanyPublishVolume(50);
int playoutVolume = mAliRtcEngine.getAudioAccompanyPlayoutVolume();
mAliRtcEngine.setAudioAccompanyPlayoutVolume(50);

// Dapatkan/Setel progres pemutaran.
int currPosition = mAliRtcEngine.getAudioAccompanyCurrentPosition(); // Posisi saat ini dalam ms.
int targetPosition = 1000; // Contoh: mulai memutar dari tanda 1000 ms.
mAliRtcEngine.setAudioAccompanyPosition(targetPosition);

iOS

// Path ke file iringan. 
let filePath = Bundle.main.path(forResource: "music", ofType: "wav")

// Konfigurasikan pemutaran iringan.
let config = AliRtcAudioAccompanyConfig()
config.loopCycles = loopCount
config.publishVolume = publishVolume
config.playoutVolume = playoutVolume
config.startPosMs = 0
// Mulai pemutaran.
let result = rtcEngine.startAudioAccompany(withFile: filePath, config: config)

// Jeda/Lanjutkan pemutaran.
rtcEngine.pauseAudioAccompany()
rtcEngine.resumeAudioAccompany()

// Hentikan pemutaran.
rtcEngine.stopAudioAccompany()

// Dapatkan durasi file iringan audio dalam ms. Panggil metode ini setelah startAudioAccompany, jika tidak akan mengembalikan -1.
let duration = rtcEngine.getAudioAccompanyDuration()
// Untuk mendapatkan durasi file tertentu, panggil getAudioFileInfo. Anda dapat memanggil ini setelah membuat engine. Hasilnya dikembalikan dalam callback onAudioFileInfo.
rtcEngine.getAudioFileInfo(filePath)
func onAudioFileInfo(_ info: AliRtcAudioFileInfo, errorCode: AliRtcAudioAccompanyErrorCode) {
    "onAudioFileInfo, filePath: \(info.filePath), durationMs: \(info.durationMs), errorCode: \(errorCode)".printLog()
}

// Dapatkan/Setel volume.
rtcEngine.setAudioAccompanyVolume(50) // Setel volume publikasi dan pemutaran sekaligus. Rentang: [0-100].
let audioPublishVolume = rtcEngine.getAudioAccompanyPublishVolume() // Dapatkan volume publikasi.
rtcEngine.setAudioAccompanyPublishVolume(50) // Setel volume publikasi. Rentang: [0-100].
let audioPlayoutVolume = rtcEngine.getAudioAccompanyPlayoutVolume() // Dapatkan volume pemutaran lokal.
rtcEngine.setAudioAccompanyPlayoutVolume(50) // Setel volume pemutaran lokal. Rentang: [0-100].

// Dapatkan/Setel progres pemutaran.
let currentPosition = rtcEngine.getAudioAccompanyCurrentPosition() // Posisi saat ini dalam ms.
let targetPosition:Int32 = 1000; // Contoh: mulai memutar dari tanda 1000 ms.
rtcEngine.setAudioAccompanyPosition(targetPosition)

Mainkan efek suara

Untuk memutar beberapa efek suara sekaligus (misalnya, tepuk tangan dan tawa), gunakan API seperti preloadAudioEffect dan playAudioEffect.

Catatan

Setiap file efek suara memerlukan ID unik. Anda harus mengelola ID-ID ini dalam aplikasi Anda.

  1. Bergabung ke saluran dan publikasikan aliran audio. Ini diaktifkan secara default di SDK.

    Android

    // Untuk memutar sumber audio eksternal, Anda harus terlebih dahulu mempublikasikan aliran audio primary. Ini diaktifkan secara default.
    mAliRtcEngine.publishLocalAudioStream(true);

    iOS

    // Untuk memutar sumber audio eksternal, Anda harus terlebih dahulu mempublikasikan aliran audio primary. Ini diaktifkan secara default. 
    engine.publishLocalAudioStream(true)
  2. (Opsional) Pra-muat sumber daya

Untuk meningkatkan performa saat memutar efek berulang kali, pra-muat file ke memori dengan memanggil preloadAudioEffect.

  • preloadAudioEffect: Memuat file efek suara yang ditentukan. Mendukung file lokal maupun URL file online. Disarankan menggunakan file lokal.

  • unloadAudioEffect: Saat file efek suara tidak lagi diperlukan, panggil API ini untuk melepasnya dan membebaskan sumber daya.

Android

// Pra-muat file efek suara dengan ID dan path file yang ditentukan. Anda harus menentukan ID tersebut.
mAliRtcEngine.preloadAudioEffect(mCurrSoundID, filePath);
// Lepaskan file efek suara dengan ID yang ditentukan.
mAliRtcEngine.unloadAudioEffect(mCurrSoundID);

iOS

// Pra-muat file efek suara dengan ID dan path file yang ditentukan. Anda harus menentukan ID tersebut.
rtcEngine.preloadAudioEffect(withSoundId: self.soundId, filePath: filePath)
// Lepaskan file efek suara dengan ID yang ditentukan.
rtcEngine.unloadAudioEffect(withSoundId: self.currentEffectIndex)
  1. Kontrol pemutaran

Setelah bergabung ke saluran dan mempublikasikan aliran audio, panggil playAudioEffect untuk memutar file efek suara. Saat pemutaran selesai, callback onAudioEffectFinished akan dipicu pada client lokal.

Gunakan API berikut untuk mengontrol pemutaran:

  • stopAudioEffect, stopAllAudioEffects: Menghentikan pemutaran.

  • pauseAudioEffect, pauseAllAudioEffects: Menjeda pemutaran.

  • resumeAudioEffect, resumeAllAudioEffects: Melanjutkan pemutaran.

  • getAudioEffectPublishVolume, setAudioEffectPublishVolume, setAllAudioEffectsPublishVolume: Mendapatkan atau mengatur volume publikasi.

  • getAudioEffectPlayoutVolume, setAudioEffectPlayoutVolume, setAllAudioEffectsPlayoutVolume: Mendapatkan atau mengatur volume pemutaran lokal.

Android

// Mainkan efek suara.
AliRtcEngine.AliRtcAudioEffectConfig config = new AliRtcEngine.AliRtcAudioEffectConfig();
config.loopCycles = -1;			// Jumlah putaran pemutaran. -1 berarti putaran tak terbatas.
config.startPosMs = 0;			// Posisi awal pemutaran dalam milidetik.
config.publishVolume = 50;		// Volume publikasi. Rentang: [0-100].
config.playoutVolume = 50;		// Volume pemutaran lokal. Rentang: [0, 100].
mAliRtcEngine.playAudioEffect(mCurrSoundID, filePath, config);

// Hentikan pemutaran.
mAliRtcEngine.stopAudioEffect(soundId);
mAliRtcEngine.stopAllAudioEffects();

// Jeda pemutaran.
mAliRtcEngine.pauseAudioEffect(soundId);
mAliRtcEngine.pauseAllAudioEffects();

// Lanjutkan pemutaran.
mAliRtcEngine.resumeAudioEffect(soundId);
mAliRtcEngine.resumeAllAudioEffects();

// Dapatkan atau atur volume.
// Volume publikasi.
mAliRtcEngine.getAudioEffectPublishVolume(soundId);
mAliRtcEngine.setAudioEffectPublishVolume(soundId, 50);
mAliRtcEngine.setAllAudioEffectsPublishVolume(50);
// Volume pemutaran.
mAliRtcEngine.getAudioEffectPlayoutVolume(soundId);
mAliRtcEngine.setAudioEffectPlayoutVolume(soundId, 50);
mAliRtcEngine.setAllAudioEffectsPlayoutVolume(50);

iOS

// Mainkan
let config = AliRtcAudioEffectConfig()
config.loopCycles = -1
config.startPosMs = 0
config.publishVolume = 50
config.playoutVolume = 50
let result = rtcEngine.playAudioEffect(withSoundId: self.soundId, filePath: filePath, config: config)
if result != 0 {
    UIAlertController.showAlertWithMainThread(msg: "Gagal memutar efek suara. Kode error: \(result)", vc: self)
}

// Hentikan pemutaran.
rtcEngine.stopAudioEffect(withSoundId: soundId)
rtcEngine.stopAllAudioEffects()

// Jeda pemutaran.
rtcEngine.pauseAudioEffect(withSoundId: soundId)
rtcEngine.pauseAllAudioEffects()

// Lanjutkan pemutaran.
rtcEngine.resumeAudioEffect(withSoundId: soundId)
rtcEngine.resumeAllAudioEffects()

// Dapatkan atau atur volume.
rtcEngine.getAudioEffectPublishVolume(withSoundId: soundId)
rtcEngine.setAudioEffectPublishVolumeWithSoundId(soundId, volume: 50)
rtcEngine.setAllAudioEffectsPublishVolume(50)
rtcEngine.resumeAudioEffect(withSoundId: soundId)    
rtcEngine.getAudioEffectPlayoutVolume(withSoundId: soundId)
rtcEngine.setAudioEffectPlayoutVolumeWithSoundId(soundId, volume: 50)

Putar atau publikasikan data audio PCM

Jika data audio yang perlu Anda putar atau publikasikan berformat PCM, rujuk metode yang dijelaskan dalam Custom audio capture.

Cara kerja

image

Kode contoh

Tambahkan aliran input eksternal

Android

/* Atur parameter sesuai kebutuhan. */
AliRtcEngine.AliRtcExternalAudioStreamConfig config = new AliRtcEngine.AliRtcExternalAudioStreamConfig();
/* Untuk menonaktifkan pemutaran lokal, atur volume playout lokal ke 0. */
config.playoutVolume = currentAudioPlayoutVolume;
/* Untuk menonaktifkan publikasi, atur volume publikasi ke 0. */
config.publishVolume = currentAudioPublishVolume;
config.channels = 1;
config.sampleRate = 48000;
// Metode ini mengembalikan ID aliran input eksternal. Gunakan ID ini untuk mendorong data ke SDK.
audioStreamID = mAliRtcEngine.addExternalAudioStream(config);

iOS

/* Atur parameter sesuai kebutuhan. */
AliRtcExternalAudioStreamConfig *config = [AliRtcExternalAudioStreamConfig new];
config.channels = _pcmChannels;
config.sampleRate = _pcmSampleRate;
/* Untuk menonaktifkan pemutaran lokal, atur volume playout ke 0. */
config.playoutVolume = 0;
/* Untuk menonaktifkan publikasi, atur volume publikasi ke 100. */
config.publishVolume = 100;
// Metode ini mengembalikan ID aliran input eksternal. Gunakan ID ini untuk mendorong data ke SDK.
_externalPlayoutStreamId = [self.engine addExternalAudioStream:config];

Dorong data PCM ke aliran audio

Android

AliRtcEngine.AliRtcAudioFrame rawData = new AliRtcEngine.AliRtcAudioFrame();
rawData.data = frameInfo.audio_data[0];
rawData.numSamples = (int) (frameInfo.audio_data[0].length / (2 * frameInfo.audio_channels));
rawData.bytesPerSample = 2;
rawData.numChannels = frameInfo.audio_channels;
rawData.samplesPerSec = frameInfo.audio_sample_rate;

int ret = mAliRtcEngine.pushExternalAudioStreamRawData(audioStreamID, rawData);
if(ret == 0x01070101) {
    // Buffer penuh.
    sleep(20);
} else if(ret < 0) {
    /* Terjadi pengecualian. Periksa parameter dan status publikasi. */
}

iOS

AliRtcAudioFrame *sample = [AliRtcAudioFrame new];
sample.dataPtr = _pcmLocalData;
sample.samplesPerSec = _pcmLocalSampleRate;
sample.bytesPerSample = sizeof(int16_t);
sample.numOfChannels = _pcmLocalChannels;
sample.numOfSamples = numOfSamples;
int rc = [self.engine pushExternalAudioStream:_externalPlayoutStreamId rawData:sample];

if(rc == 0x01070101) {
    // Buffer penuh.
    sleep(20);
} else if(ret < 0) {
    /* Terjadi pengecualian. Periksa parameter dan status publikasi. */
}

Hapus aliran audio eksternal

Android

mAliRtcEngine.removeExternalAudioStream(audioStreamID);

iOS

[self.engine removeExternalAudioStream:_externalPublishStreamId];

FAQ

  1. Bagaimana cara menggunakan startAudioAccompany untuk hanya mempublikasikan iringan, bukan audio mikrofon saya?

    Panggil metode muteLocalMic sebelum atau selama pemutaran iringan. Hal ini akan membisukan input mikrofon Anda, sehingga pengguna remote hanya akan mendengar audio dari aliran iringan.