Misture áudio externo — como música de fundo, efeitos sonoros ou fluxos PCM — ao fluxo de áudio do ARTC SDK para reprodução local e compartilhamento remoto.
Visão geral
O ARTC SDK aceita entrada de áudio externo nos formatos MP4, WAV, AAC e PCM. Integre arquivos pré-gravados ou fluxos de dados em tempo real.
Casos de uso
Publicação de arquivos de áudio: Insira efeitos sonoros, música de fundo ou conteúdo falado em transmissões ao vivo, como alertas de produtos no comércio eletrônico ou efeitos ambientes em jogos.
Publicação de fluxos PCM: Ideal para serviços de voz em tempo real, como a publicação de áudio PCM gerado por TTS em sistemas de atendimento ao cliente.
Código de exemplo
Android: Android/ARTCExample/BasicUsage/src/main/java/com/aliyun/artc/api/basicusage/PlayAudioFiles/PlayAudioFilesActivity.java
iOS: iOS/ARTCExample/BasicUsage/PlayAudioFiles/PlayAudioFilesVC.swift
Harmony: Harmony/ARTCExample/entry/src/main/ets/pages/basicusage/PlayAudioFilesPage.ets.
Antes de começar
Antes de iniciar, verifique os seguintes requisitos:
Possuir uma conta Alibaba Cloud e ter criado um aplicativo ARTC (Crie um aplicativo). Obtenha o AppID e a AppKey no console do ApsaraVideo Live.
Ter integrado o ARTC SDK (Integrar o SDK) e implementado chamadas básicas de áudio e vídeo (Implementar uma chamada de áudio e vídeo).
Reproduzir ou publicar arquivos de áudio
Como funciona
Dois conjuntos de APIs estão disponíveis para reproduzir ou publicar arquivos de áudio:
APIs de acompanhamento: Reproduzem arquivos de áudio mais longos, como música de fundo. Apenas um arquivo pode ser reproduzido por vez.
APIs de efeitos sonoros: Reproduzem clipes de áudio curtos, como aplausos ou risadas. Vários efeitos podem ser reproduzidos simultaneamente.
Antes de reproduzir ou publicar áudio externo, entre em um canal e publique seu fluxo de áudio local. Aguarde o callback onAudioPublishStateChanged para confirmar a publicação.
APIs relacionadas:
|
Recurso |
APIs de acompanhamento |
APIs de efeitos sonoros |
|
Controlar reprodução |
|
|
|
Gerencie progresso da reprodução |
|
|
|
Gerencie volume de reprodução |
|
|
|
Callbacks de status de reprodução |
Local:
Remoto:
|
Local:
|
|
Obter informações do arquivo de áudio |
|
|
Reproduzir um acompanhamento
As APIs de acompanhamento reproduzem apenas um arquivo de áudio por vez.
-
Entre em um canal e publique o fluxo de áudio. Habilitado por padrão.
Android
// To play an accompaniment or sound effect, you must publish the audio stream. This is enabled by default in the SDK. mAliRtcEngine.publishLocalAudioStream(true);iOS
// To play an accompaniment or sound effect, you must publish the audio stream. This is enabled by default in the SDK. engine.publishLocalAudioStream(true)Harmony
// Publish the local audio stream. This is enabled by default. this.rtcEngine.publishLocalAudioStream(true);Mac
// To play an accompaniment or sound effect, you must publish the audio stream. This is enabled by default in the SDK. [self.engine publishLocalAudioStream:TRUE];Windows
mAliRtcEngine->publishLocalAudioStream(true) Controle a reprodução
Chame startAudioAccompany para iniciar a reprodução. Isso aciona onAudioAccompanyStateChanged localmente e onRemoteAudioAccompanyStarted remotamente.
Outras APIs de controle de reprodução:
stopAudioAccompany: Para a reprodução.pauseAudioAccompany: Pausa a reprodução.resumeAudioAccompany: Retoma a reprodução.getAudioAccompanyDuration, getAudioAccompanyCurrentPosition, setAudioAccompanyPosition: Obtém a duração e controla o progresso da reprodução.setAudioAccompanyVolume: Defina o volume de reprodução local e de publicação remota.getAudioAccompanyPublishVolume, setAudioAccompanyPublishVolume: Obtém ou defina o volume de publicação remota.getAudioAccompanyPlayoutVolume, setAudioAccompanyPlayoutVolume: Obtém ou defina o volume de reprodução local.
Android
// Path to the accompaniment file.
private String mMixingMusicFilepath = "/assets/music.wav";
// Configure accompaniment playback.
AliRtcEngine.AliRtcAudioAccompanyConfig config = new AliRtcEngine.AliRtcAudioAccompanyConfig();
config.loopCycles = -1; // Number of loops. -1 indicates infinite looping.
config.publishVolume = publishVolume; // Publishing volume. Range: [0, 100].
config.playoutVolume = playbackVolume; // Local playback volume. Range: [0, 100].
config.startPosMs = 0; // Playback starting position.
// Start playback.
mAliRtcEngine.startAudioAccompany(mMixingMusicFilepath, config);
// Pause/Resume the accompaniment.
mAliRtcEngine.pauseAudioAccompany();
mAliRtcEngine.resumeAudioAccompany();
// Stop playback.
mAliRtcEngine.stopAudioAccompany();
// Get the duration of the accompaniment file in ms. Call this method after startAudioAccompany, otherwise it returns -1.
int duration = mAliRtcEngine.getAudioAccompanyDuration();
// To get the duration of a specific file, call getAudioFileInfo. You can call this after creating the engine. The result is returned in the onAudioFileInfo callback.
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);
});
}
// Get/Set the volume.
mAliRtcEngine.setAudioAccompanyVolume(50); // Range: [0, 100].
int publishVolume = mAliRtcEngine.getAudioAccompanyPublishVolume();
mAliRtcEngine.setAudioAccompanyPublishVolume(50);
int playoutVolume = mAliRtcEngine.getAudioAccompanyPlayoutVolume();
mAliRtcEngine.setAudioAccompanyPlayoutVolume(50);
// Get/Set playback progress.
int currPosition = mAliRtcEngine.getAudioAccompanyCurrentPosition(); // Unit: ms.
int targetPosition = 1000; // Example: start playing from the 1000 ms mark.
mAliRtcEngine.setAudioAccompanyPosition(targetPosition);
iOS
// Path to the accompaniment file.
let filePath = Bundle.main.path(forResource: "music", ofType: "wav")
// Configure accompaniment playback.
let config = AliRtcAudioAccompanyConfig()
config.loopCycles = loopCount
config.publishVolume = publishVolume
config.playoutVolume = playoutVolume
config.startPosMs = 0
// Start playback.
let result = rtcEngine.startAudioAccompany(withFile: filePath, config: config)
// Pause/Resume playback.
rtcEngine.pauseAudioAccompany()
rtcEngine.resumeAudioAccompany()
// Stop playback.
rtcEngine.stopAudioAccompany()
// Get the duration of the accompaniment file in ms. Call this method after startAudioAccompany, otherwise it returns -1.
let duration = rtcEngine.getAudioAccompanyDuration()
// To get the duration of a specific file, call getAudioFileInfo. You can call this after creating the engine. The result is returned in the onAudioFileInfo callback.
rtcEngine.getAudioFileInfo(filePath)
func onAudioFileInfo(_ info: AliRtcAudioFileInfo, errorCode: AliRtcAudioAccompanyErrorCode) {
"onAudioFileInfo, filePath: \(info.filePath), durationMs: \(info.durationMs), errorCode: \(errorCode)".printLog()
}
// Get/Set the volume.
rtcEngine.setAudioAccompanyVolume(50) // Set both the publishing and playback volume of the accompaniment. Range: [0-100].
let audioPublishVolume = rtcEngine.getAudioAccompanyPublishVolume() // Get the current publishing volume of the accompaniment.
rtcEngine.setAudioAccompanyPublishVolume(50) // Set the publishing volume of the accompaniment. Range: [0-100].
let audioPlayoutVolume = rtcEngine.getAudioAccompanyPlayoutVolume() // Get the current local playback volume of the accompaniment.
rtcEngine.setAudioAccompanyPlayoutVolume(50) // Set the local playback volume of the accompaniment. Range: [0-100].
// Get/Set playback progress.
let currentPosition = rtcEngine.getAudioAccompanyCurrentPosition() // Unit: ms.
let targetPosition:Int32 = 1000; // Example: start playing from the 1000 ms mark.
rtcEngine.setAudioAccompanyPosition(targetPosition)
Harmony
// Path to the accompaniment file.
private accompanimentFile: string = 'music.wav';
// Start the accompaniment.
private async startAudioAccompany(): Promise<void> {
if (!this.rtcEngine) {
prompt.showToast({ message: 'RTC engine not initialized', duration: 2000 });
return;
}
if (!this.hasJoined) {
prompt.showToast({ message: 'Join a channel first', duration: 2000 });
return;
}
try {
// Get the loop count.
const loopCount = this.loopCount.trim() === '' ? -1 : parseInt(this.loopCount);
const publishVolume = this.pushVolume; // Publishing volume.
const playbackVolume = this.playVolume; // Local playback volume.
// Create an accompaniment configuration.
const config: AliRtcAudioAccompanyConfig = new AliRtcAudioAccompanyConfig();
config.loopCycles = loopCount; // Number of loops. -1 indicates infinite looping.
config.publishVolume = publishVolume; // Publishing volume. Range: [0, 100].
config.playoutVolume = playbackVolume; // Local playback volume. Range: [0, 100].
config.startPosMs = 0; // Playback starting position.
// Use the sandbox file path.
const audioPath = this.sandboxManager.getSandboxFilePath(this.accompanimentFile);
// Start playback.
this.rtcEngine.startAudioAccompany(audioPath, config);
// Get the audio duration and update the progress bar.
const audioDuration = this.rtcEngine.getAudioAccompanyDuration(); // Unit: ms.
if (audioDuration > 0) {
this.audioDuration = audioDuration;
}
console.info('Start playing accompaniment');
} catch (error) {
console.error('Error playing accompaniment:', error);
prompt.showToast({ message: 'Error playing accompaniment', duration: 2000 });
}
}
// Pause the accompaniment.
private pauseAudioAccompany(): void {
if (!this.rtcEngine) {
prompt.showToast({ message: 'RTC engine not initialized', duration: 2000 });
return;
}
this.rtcEngine.pauseAudioAccompany();
console.info('Pause accompaniment playback');
}
// Resume the accompaniment.
private resumeAudioAccompany(): void {
if (!this.rtcEngine) {
prompt.showToast({ message: 'RTC engine not initialized', duration: 2000 });
return;
}
this.rtcEngine.resumeAudioAccompany();
console.info('Resume accompaniment playback');
}
// Stop the accompaniment.
private stopAudioAccompany(): void {
if (!this.rtcEngine) {
prompt.showToast({ message: 'RTC engine not initialized', duration: 2000 });
return;
}
this.rtcEngine.stopAudioAccompany();
console.info('Stop accompaniment playback');
}
// Set the accompaniment volume.
private setAudioAccompanyVolume(volume: number): void {
if (this.rtcEngine && this.hasJoined) {
this.rtcEngine.setAudioAccompanyVolume(volume); // Range: [0, 100].
}
}
// Set the publishing volume.
private setAudioAccompanyPublishVolume(volume: number): void {
if (this.rtcEngine && this.hasJoined) {
this.rtcEngine.setAudioAccompanyPublishVolume(volume); // Range: [0, 100].
}
}
// Set the playback volume.
private setAudioAccompanyPlayoutVolume(volume: number): void {
if (this.rtcEngine && this.hasJoined) {
this.rtcEngine.setAudioAccompanyPlayOutVolume(volume); // Range: [0, 100].
}
}
// Get the publishing volume.
private getAudioAccompanyPublishVolume(): number {
if (this.rtcEngine) {
return this.rtcEngine.getAudioAccompanyPublishVolume();
}
return 0;
}
// Get the playback volume.
private getAudioAccompanyPlayoutVolume(): number {
if (this.rtcEngine) {
return this.rtcEngine.getAudioAccompanyPlayoutVolume();
}
return 0;
}
// Set the playback position.
private setAudioAccompanyPosition(position: number): void {
if (this.rtcEngine && this.hasJoined) {
if (position >= 0 && position <= this.audioDuration) {
this.rtcEngine.setAudioAccompanyPosition(position); // Unit: ms.
}
}
}
// Get the current playback position.
private getAudioAccompanyCurrentPosition(): number {
if (this.rtcEngine && this.hasJoined) {
return this.rtcEngine.getAudioAccompanyCurrentPosition(); // Unit: ms.
}
return 0;
}
// Example of a timer to update playback progress.
private updatePlayProgress(): void {
if (this.rtcEngine && this.hasJoined) {
const currentPosition = this.rtcEngine.getAudioAccompanyCurrentPosition();
this.playProgress = currentPosition;
}
}
Mac
AliRtcAudioAccompanyConfig *config = [[AliRtcAudioAccompanyConfig alloc] init];
config.onlyLocalPlay = localPlay;
config.replaceMic = replaceMic;
config.loopCycles = self.loopLabel.intValue;
config.startPosMs = startPosMs;
config.publishVolume = publishVolume;
config.playoutVolume = playVolume;
NSString *string;
int ret = [self.engine startAudioAccompanyWithFile:self.playURLString config:config];
if (ret) {
string = [NSString stringWithFormat:@"Playback failed. Check the parameter configuration: %d",ret];
} else {
[self.isChangeMicBtn setEnabled:FALSE] ;
if (startPos > 0 && startPosMs == 0) {
string = @"Playback started successfully (music duration not available, start position parameter ignored)";
} else {
string = @"Playback started successfully";
}
}
// Pause/Resume playback.
[self.engine pauseAudioAccompany];
[self.engine resumeAudioAccompany];
// Stop playback.
[self.engine stopAudioAccompany];
// Get the duration of the accompaniment file in ms. Call this method after startAudioAccompany, otherwise it returns -1.
int duration = [self.engine getAudioAccompanyDuration];
// To get the duration of a specific file, call getAudioFileInfo. You can call this after creating the engine. The result is returned in the onAudioFileInfo callback.
[self.engine getAudioFileInfo:filePath];
- (void)onAudioFileInfo:(AliRtcAudioFileInfo* _Nonnull)info errorCode:(AliRtcAudioAccompanyErrorCode)errorCode {
/* Update UI status */
dispatch_async(dispatch_get_main_queue(), ^{
if (self.accompanyVC) {
[self.accompanyVC updateAudioFileInfo:info errorCode:errorCode];
}
if (self.effectVC) {
[self.effectVC updateAudioFileInfo:info errorCode:errorCode];
}
});
}
// Get/Set volume.
[self.engine setAudioAccompanyVolume:sender.integerValue];
// Set both the publishing and playback volume of the accompaniment. Range: [0, 100].
int volume = [self.engine getAudioAccompanyPublishVolume];
sender.title = [NSString stringWithFormat:@"Get publishing volume: %d",volume];
[self.engine setAudioAccompanyPublishVolume:50]; // Set the publishing volume of the accompaniment. Range: [0, 100].
int audioPlayoutVolume = [self.engine getAudioAccompanyPlayoutVolume]; // Get the current local playback volume of the accompaniment.
[self.engine setAudioAccompanyPlayoutVolume:50]; // Set the local playback volume of the accompaniment. Range: [0, 100].
// Get/Set playback progress.
int duration = [self.engine getAudioAccompanyDuration];
long position = duration * sender.integerValue/100;
[self.engine setAudioAccompanyPosition:(int)position];
Windows
AliEngineAudioAccompanyConfig config;
config.onlyLocalPlay = (0 == mbCheckPubAcc);
config.loopCycles = miEditCycleNum;
config.replaceMic = (0 != mbCheckAccReplaceMic);
config.startPosMs = startPosMs;
config.playoutVolume = mbCheckAccMixVol ? miStaticAccMixVol : miStaticAccPlayoutVol;
config.publishVolume = mbCheckAccMixVol ? miStaticAccMixVol : miStaticAccPubVol;
if (0 != mAliRtcEngine->StartAudioAccompany(strPath.c_str(), config))
{
AfxMessageBox(_T("Failed to start accompaniment!"));
return;
}
// Pause/Resume the accompaniment.
mAliRtcEngine->PauseAudioAccompany();
mAliRtcEngine->ResumeAudioAccompany();
// Stop playback.
mAliRtcEngine->StopAudioAccompany();
// Get the duration of the accompaniment file in ms. Call this method after startAudioAccompany, otherwise it returns -1.
int duration = mAliRtcEngine->GetAudioAccompanyDuration();
// To get the duration of a specific file, call getAudioFileInfo. You can call this after creating the engine. The result is returned in the onAudioFileInfo callback.
mAliRtcEngine->GetAudioFileInfo(filePath);
void CTutorialDlg::OnAudioFileInfo(AliEngineAudioFileInfo info,
AliEngineAudioAccompanyErrorCode errorCode) {
/* Notify the UI to refresh. */
CAudioAccompanyDlg::AudioFileInfo *audioInfo = new CAudioAccompanyDlg::AudioFileInfo();
audioInfo->filePath = AliStringToCString(info.filePath);
audioInfo->durationMs = info.durationMs;
::PostMessage(cshell_dlg.GetAudioAccompanyHwnd(), MM_AUDIO_ACCOMPANY_AUDIO_FILE_INFO, (WPARAM)audioInfo, (LPARAM)errorCode);
CAudioEffectDlg::AudioFileInfo *effectInfo = new CAudioEffectDlg::AudioFileInfo();
effectInfo->filePath = AliStringToCString(info.filePath);
effectInfo->durationMs = info.durationMs;
::PostMessage(cshell_dlg.GetAudioEffectHwnd(), MM_AUDIO_EFFECT_AUDIO_FILE_INFO, (WPARAM)effectInfo, (LPARAM)errorCode);
}
/* Get/Set the volume. */
mAliRtcEngine->SetAudioAccompanyVolume(50); // Range: [0, 100].
int publishVolume = mAliRtcEngine->GetAudioAccompanyPublishVolume();
mAliRtcEngine->SetAudioAccompanyPublishVolume(50);
int playoutVolume = mAliRtcEngine->GetAudioAccompanyPlayoutVolume();
mAliRtcEngine->SetAudioAccompanyPlayoutVolume(50);
/* Get/Set playback progress. */
int currPosition = mAliRtcEngine->GetAudioAccompanyCurrentPosition(); // Unit: ms.
int targetPosition = 1000; // Example: start playing from the 1000 ms mark.
mAliRtcEngine->SetAudioAccompanyPosition(targetPosition);
Reproduzir efeitos sonoros
Use preloadAudioEffect e playAudioEffect para reproduzir vários efeitos sonoros simultaneamente.
Atribua um ID exclusivo a cada efeito sonoro. Seu aplicativo deve gerenciar esses IDs.
-
Entre em um canal e publique o fluxo de áudio. Habilitado por padrão no SDK.
Android
// To play an accompaniment or sound effect, you must publish the audio stream. This is enabled by default in the SDK. mAliRtcEngine.publishLocalAudioStream(true);iOS
// To play an accompaniment or sound effect, you must publish the audio stream. This is enabled by default in the SDK. engine.publishLocalAudioStream(true)Harmony
// Publish the local audio stream. This is enabled by default. this.rtcEngine.publishLocalAudioStream(true);Mac
// To play an accompaniment or sound effect, you must publish the audio stream. This is enabled by default in the SDK. [self.engine publishLocalAudioStream:TRUE];Windows
mAliRtcEngine->PublishLocalAudioStream(true); (Opcional) Pré-carregue recursos
Para reprodução repetida, pré-carregue o arquivo de áudio na memória com preloadAudioEffect.
preloadAudioEffect: Carrega um arquivo de efeito sonoro. Suporta arquivos locais e URLs de rede. Recomenda-se o uso de arquivos locais.Chame
unloadAudioEffectpara descarregar um efeito sonoro e liberar recursos.
Android
// Load the sound effect file with the specified ID and filePath. You must define the ID.
mAliRtcEngine.preloadAudioEffect(mCurrSoundID, filePath);
// Unload the sound effect file with the specified ID.
mAliRtcEngine.unloadAudioEffect(mCurrSoundID);
iOS
// Load the sound effect file with the specified ID and filePath. You must define the ID.
rtcEngine.preloadAudioEffect(withSoundId: self.soundId, filePath: filePath)
// Unload the sound effect file with the specified ID.
rtcEngine.unloadAudioEffect(withSoundId: self.currentEffectIndex)
Harmony
// Load the sound effect file with the specified ID and filePath. You must define the ID.
this.rtcEngine.preloadAudioEffect(1, audioPath);
// Unload the sound effect file with the specified ID.
this.rtcEngine.unloadAudioEffect(this.currSoundID);
Mac
// Load the sound effect file with the specified ID and filePath. You must define the ID.
[self.engine preloadAudioEffectWithSoundId:weakSelf.currentIndex filePath:chooseFileString];
// Unload the sound effect file with the specified ID.
[self.engine unloadAudioEffectWithSoundId:info.effectId];
Windows
// Load the sound effect file with the specified ID and filePath. You must define the ID.
mAliRtcEngine->PreloadAudioEffect(mCurrSoundID, filePath);
// Unload the sound effect file with the specified ID.
mAliRtcEngine->UnloadAudioEffect(mCurrSoundID);
Controle a reprodução
Chame playAudioEffect para reproduzir um efeito sonoro. O callback onAudioEffectFinished é disparado quando a reprodução termina.
Outras APIs de controle de reprodução:
stopAudioEffect/stopAllAudioEffects: Para um efeito sonoro específico ou todos os efeitos.pauseAudioEffect/pauseAllAudioEffects: Pausa um efeito sonoro específico ou todos os efeitos.resumeAudioEffect/resumeAllAudioEffects: Retoma um efeito sonoro específico ou todos os efeitos.getAudioEffectPublishVolume, setAudioEffectPublishVolume, setAllAudioEffectsPublishVolume: Obtém ou defina o volume de publicação remota.getAudioEffectPlayoutVolume, setAudioEffectPlayoutVolume, setAllAudioEffectsPlayoutVolume: Obtém ou defina o volume de reprodução local.
Android
// Play the sound effect.
AliRtcEngine.AliRtcAudioEffectConfig config = new AliRtcEngine.AliRtcAudioEffectConfig();
config.loopCycles = -1; // Number of loops. -1 indicates infinite looping.
config.startPosMs = 0; // Playback starting position.
config.publishVolume = 50; // Publishing volume. Range: [0, 100].
config.playoutVolume = 50; // Local playback volume. Range: [0, 100].
mAliRtcEngine.playAudioEffect(mCurrSoundID, filePath, config);
// Stop playback.
mAliRtcEngine.stopAudioEffect(soundId);
mAliRtcEngine.stopAllAudioEffects();
// Pause playback.
mAliRtcEngine.pauseAudioEffect(soundId);
mAliRtcEngine.pauseAllAudioEffects();
// Resume playback.
mAliRtcEngine.resumeAudioEffect(soundId);
mAliRtcEngine.resumeAllAudioEffects();
// Get or set the volume.
// Publishing volume
mAliRtcEngine.getAudioEffectPublishVolume(soundId);
mAliRtcEngine.setAudioEffectPublishVolume(soundId, 50);
mAliRtcEngine.setAllAudioEffectsPublishVolume(50);
// Playback volume
mAliRtcEngine.getAudioEffectPlayoutVolume(soundId);
mAliRtcEngine.setAudioEffectPlayoutVolume(soundId, 50);
mAliRtcEngine.setAllAudioEffectsPlayoutVolume(50);
iOS
// Play
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: "Failed to play sound effect. Error code: \(result)", vc: self)
}
// Stop playback.
rtcEngine.stopAudioEffect(withSoundId: soundId)
rtcEngine.stopAllAudioEffects()
// Pause playback.
rtcEngine.pauseAudioEffect(withSoundId: soundId)
rtcEngine.pauseAllAudioEffects()
// Resume playback.
rtcEngine.resumeAudioEffect(withSoundId: soundId)
rtcEngine.resumeAllAudioEffects()
// Get or set the 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)
Harmony
// Play
const config: AliRtcAudioEffectConfig = new AliRtcAudioEffectConfig();
config.loopCycles = loopCount;
config.startPosMs = 0;
config.publishVolume = this.soundEffectVolume;
config.playoutVolume = this.soundEffectVolume;
const audioPath = this.sandboxManager.getSandboxFilePath(filePath);
this.rtcEngine.playAudioEffect(this.currSoundID, audioPath, config);
// Stop playback.
this.rtcEngine.stopAudioEffect(soundId);
this.rtcEngine.stopAllAudioEffects();
// Pause playback.
this.rtcEngine.pauseAudioEffect(soundId);
this.rtcEngine.pauseAllAudioEffects();
// Resume playback.
this.rtcEngine.resumeAudioEffect(soundId);
this.rtcEngine.resumeAllAudioEffects();
Mac
// Play
AliRtcAudioEffectConfig *config = [AliRtcAudioEffectConfig new];
config.loopCycles = self.circleCountLabel.intValue;
config.needPublish = publish;
config.playoutVolume = info.playoutVolume;
config.publishVolume = info.publishVolume;
config.startPosMs = startPosMs;
int ret = [self.engine playAudioEffectWithSoundId:info.effectId filePath:self.playURLString config:config];
// Stop playback.
[self.engine stopAudioEffectWithSoundId:effectId];
[self.engine stopAllAudioEffects];
// Pause playback.
[self.engine pauseAudioEffectWithSoundId:effectId];
[self.engine pauseAllAudioEffects];
// Resume playback.
[self.engine resumeAudioEffectwithSoundId:soundId];
[self.engine resumeAllAudioEffects];
// Get or set the volume.
int volume = [self.engine getAudioEffectPublishVolumeWithSoundId:soundId];
[self.engine setAudioEffectPublishVolumeWithSoundId:soundId volume: 50];
[self.engine setAllAudioEffectsPublishVolume:50];
[self.engine resumeAudioEffectwithSoundId: soundId];
[self.engine getAudioEffectPlayoutVolumewithSoundId: soundId];
[self.engine setAudioEffectPlayoutVolumeWithSoundId:soundId volume: 50];
Windows
// Play the sound effect.
AliEngineAudioEffectConfig config ;
config.loopCycles = -1; // Number of loops. -1 indicates infinite looping.
config.startPosMs = 0; // Playback starting position.
config.publishVolume = 50; // Publishing volume. Range: [0, 100].
config.playoutVolume = 50; // Local playback volume. Range: [0, 100].
mAliRtcEngine->PlayAudioEffect(mCurrSoundID, filePath, config);
// Stop playback.
mAliRtcEngine->StopAudioEffect(soundId);
mAliRtcEngine->StopAllAudioEffects();
// Pause playback.
mAliRtcEngine->PauseAudioEffect(soundId);
mAliRtcEngine->PauseAllAudioEffects();
// Resume playback.
mAliRtcEngine->ResumeAudioEffect(soundId);
mAliRtcEngine->ResumeAllAudioEffects();
// Get or set the volume.
// Publishing volume
mAliRtcEngine->GetAudioEffectPublishVolume(soundId);
mAliRtcEngine->SetAudioEffectPublishVolume(soundId, 50);
mAliRtcEngine->SetAllAudioEffectsPublishVolume(50);
// Playback volume
mAliRtcEngine->GetAudioEffectPlayoutVolume(soundId);
mAliRtcEngine->SetAudioEffectPlayoutVolume(soundId, 50);
mAliRtcEngine->SetAllAudioEffectsPlayoutVolume(50);
Reproduzir ou publicar dados de áudio PCM
O áudio PCM utiliza as APIs de Captura de áudio personalizada.
Como funciona
Código de exemplo
Adicionar um fluxo de entrada externo
Android
/* Set the parameters based on your business needs. */
AliRtcEngine.AliRtcExternalAudioStreamConfig config = new AliRtcEngine.AliRtcExternalAudioStreamConfig();
/* Set the playout volume to 0 to disable local playback. */
config.playoutVolume = currentAudioPlayoutVolume;
/* Set the publishing volume to 0 to disable publishing. */
config.publishVolume = currentAudioPublishVolume;
config.channels = 1;
config.sampleRate = 48000;
// The method returns an external input stream ID. Use this ID to push data into the SDK.
audioStreamID = mAliRtcEngine.addExternalAudioStream(config);
iOS
/* Set the parameters based on your business needs. */
AliRtcExternalAudioStreamConfig *config = [AliRtcExternalAudioStreamConfig new];
config.channels = _pcmChannels;
config.sampleRate = _pcmSampleRate;
/* Set the playout volume to 0 to disable local playback. */
config.playoutVolume = 0;
/* Set the publishing volume to 100. This example uses 100, but you can set it to 0 to disable publishing. */
config.publishVolume = 100;
// The method returns an external input stream ID. Use this ID to push data into the SDK.
_externalPlayoutStreamId = [self.engine addExternalAudioStream:config];
Enviar dados PCM para o fluxo
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) {
// The buffer is full.
sleep(20);
} else if(ret < 0) {
/* An exception occurred. Check the parameters and publishing state. */
}
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) {
// The buffer is full.
sleep(20);
} else if(ret < 0) {
/* An exception occurred. Check the parameters and publishing state. */
}
Remover o fluxo de áudio externo
Android
mAliRtcEngine.removeExternalAudioStream(audioStreamID);
iOS
[self.engine removeExternalAudioStream:_externalPublishStreamId];
Perguntas frequentes
-
Como permitir que apenas usuários remotos ouçam o acompanhamento do
startAudioAccompanysem o áudio do meu microfone?Chame
muteLocalMicantes ou durante a reprodução para silenciar o microfone. Assim, os usuários remotos ouvirão apenas o acompanhamento.