すべてのプロダクト
Search
ドキュメントセンター

ApsaraVideo Live:外部音声 (効果音と伴奏) の再生と公開

最終更新日:Mar 26, 2026

このトピックでは、リアルタイムセッション中に、BGM、効果音、PCM 音声ストリームなどの外部音声を ARTC SDK 音声ストリームにミキシングして、ローカル再生およびリモート共有を行う方法について説明します。

概要

ARTC SDK を使用すると、外部音声を再生および公開できます。MP4、WAV、AAC などのさまざまなファイル形式や、PCM 音声ストリームをサポートしています。ユースケースに応じて、事前録音ファイルまたはリアルタイムデータストリームを統合できます。

ユースケース

  • 音声ファイルの公開: ライブストリームに効果音、BGM、または音声コンテンツを挿入します。たとえば、eコマースストリームでプロダクトアラートをトリガーしたり、ゲームストリームで環境効果音を追加したりできます。

  • PCM ストリームの公開: 音声合成 (TTS) で生成された PCM 音声ストリームをインテリジェントカスタマーサービスシステムで公開するなど、リアルタイムインタラクティブ音声サービスに最適です。

サンプルコード

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

事前準備

このトピックの機能を実装する前に、次の要件を満たしていることを確認してください。

音声ファイルの再生または公開

仕組み

この機能を使用すると、リアルタイムセッション中に音声ファイルを再生または公開できます。さまざまなユースケースに対応する 2 セットの API を提供します。

  • 伴奏 API: BGM や伴奏など、より長い音声ファイルを再生する場合に使用します。一度に 1 つの音楽ファイルのみを再生できます。

  • 効果音 API: 拍手や笑い声など、短く一時的なオーディオクリップの再生に最適化されています。複数の効果音を同時に再生できます。

説明

外部音声を再生または公開する前に、チャンネルに参加し、ローカル音声ストリームを公開する必要があります。音声ストリームが公開されたことを確認する onAudioPublishStateChanged コールバックを待機してください。

関連 API は次のとおりです。

機能

伴奏 API

効果音 API

再生を制御

  • startAudioAccompany

  • stopAudioAccompany

  • pauseAudioAccompany

  • resumeAudioAccompany

  • preloadAudioEffect

  • unloadAudioEffect

  • playAudioEffect

  • stopAudioEffect

  • stopAllAudioEffects

  • pauseAudioEffect

  • pauseAllAudioEffects

  • resumeAudioEffect

  • resumeAllAudioEffects

再生進行状況の管理

  • getAudioAccompanyDuration

  • getAudioAccompanyCurrentPosition

  • setAudioAccompanyPosition


再生音量の管理

  • setAudioAccompanyVolume

  • setAudioAccompanyPublishVolume

  • getAudioAccompanyPublishVolume

  • setAudioAccompanyPlayoutVolume

  • getAudioAccompanyPlayoutVolume

  • setAudioEffectPublishVolume

  • getAudioEffectPublishVolume

  • setAudioEffectPlayoutVolume

  • getAudioEffectPlayoutVolume

  • setAllAudioEffectsPublishVolume

  • setAllAudioEffectsPlayoutVolume

再生ステータスコールバック

ローカル:

  • onAudioAccompanyStateChanged

リモート:

  • onRemoteAudioAccompanyStarted

  • onRemoteAudioAccompanyFinished

ローカル:

  • onAudioEffectFinished

音声ファイル情報の取得

  • getAudioFileInfo

  • onAudioFileInfo

伴奏の再生

伴奏 API を使用する場合、一度に 1 つの音声ファイルのみを再生できます。

  1. チャンネルに参加し、音声ストリームを公開します。これは 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)
  2. 再生を制御

チャンネルに参加して音声ストリームをプッシュした後、startAudioAccompany を呼び出して伴奏を再生します。呼び出しが成功すると、ローカルで onAudioAccompanyStateChanged コールバックがトリガーされ、リモートで onRemoteAudioAccompanyStarted コールバックがトリガーされます。

次の API を使用して再生を制御することもできます。

  • stopAudioAccompany: 再生を停止します。

  • pauseAudioAccompany: 再生を一時停止します。

  • resumeAudioAccompany: 再生を再開します。

  • getAudioAccompanyDuration, getAudioAccompanyCurrentPosition, setAudioAccompanyPosition: ファイルの持続時間を取得し、再生進行状況を制御します。

  • setAudioAccompanyVolume: 伴奏のローカル再生音量とリモート公開音量の両方を設定します。

  • getAudioAccompanyPublishVolume, setAudioAccompanyPublishVolume: リモートクライアント向けの伴奏の公開音量を取得または調整します。

  • getAudioAccompanyPlayoutVolume, setAudioAccompanyPlayoutVolume: 伴奏のローカル再生音量を取得または調整します。

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);

効果音の再生

複数の効果音を同時に再生する (たとえば、拍手と笑い声) には、preloadAudioEffectplayAudioEffect などの API を使用します。

説明

各効果音には一意の ID を割り当てる必要があります。アプリケーションはこれらの ID の管理を担当します。

  1. チャンネルに参加し、音声ストリームを公開します。これは 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);
  2. (オプション) リソースのプリロード

効果音を繰り返し再生する際のパフォーマンスを向上させるには、preloadAudioEffect を呼び出して音声ファイルをメモリにプリロードすることを推奨します。

  • preloadAudioEffect: 指定された効果音ファイルをロードします。ローカルファイルとネットワークファイル URL の両方をサポートしています。ローカルファイルの使用を推奨します。

  • 効果音が不要になった場合は、unloadAudioEffect を呼び出してアンロードし、リソースを解放します。

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);
  1. 再生を制御

チャンネルに参加して音声ストリームを公開した後、playAudioEffect を呼び出して効果音を再生します。再生が完了すると、ローカルクライアントで onAudioEffectFinished コールバックがトリガーされます。

次の API を使用して再生を制御することもできます。

  • stopAudioEffect/stopAllAudioEffects: 特定の効果音またはすべての効果音の再生を停止します。

  • pauseAudioEffect/pauseAllAudioEffects: 特定の効果音またはすべての効果音の再生を一時停止します。

  • resumeAudioEffect/resumeAllAudioEffects: 特定の効果音またはすべての効果音の再生を再開します。

  • getAudioEffectPublishVolume, setAudioEffectPublishVolume, setAllAudioEffectsPublishVolume: リモートクライアント向けの効果音の公開音量を取得または調整します。

  • getAudioEffectPlayoutVolume, setAudioEffectPlayoutVolume, setAllAudioEffectsPlayoutVolume: 効果音のローカル再生音量を取得または調整します。

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);

PCM 音声データの再生または公開

PCM 音声データの再生または公開については、「カスタム音声キャプチャ」をご参照ください。

仕組み

image

サンプルコード

外部入力ストリームの追加

Android

/* ビジネス要件に基づいてパラメーターを設定します。 */
AliRtcEngine.AliRtcExternalAudioStreamConfig config = new AliRtcEngine.AliRtcExternalAudioStreamConfig();
/* ローカル再生を無効にするには、再生ボリュームを 0 に設定します。 */
config.playoutVolume = currentAudioPlayoutVolume;
/* 公開を無効にするには、公開ボリュームを 0 に設定します。 */
config.publishVolume = currentAudioPublishVolume;
config.channels = 1;
config.sampleRate = 48000;
// このメソッドは外部入力ストリーム ID を返します。この ID を使用して SDK にデータをプッシュします。
audioStreamID = mAliRtcEngine.addExternalAudioStream(config);

iOS

/* ビジネス要件に基づいてパラメーターを設定します。 */
AliRtcExternalAudioStreamConfig *config = [AliRtcExternalAudioStreamConfig new];
config.channels = _pcmChannels;
config.sampleRate = _pcmSampleRate;
/* ローカル再生を無効にするには、再生ボリュームを 0 に設定します。 */
config.playoutVolume = 0;
/* 公開ボリュームを 100 に設定します。この例では 100 を使用していますが、公開を無効にするには 0 に設定できます。 */
config.publishVolume = 100;
// このメソッドは外部入力ストリーム ID を返します。この ID を使用して SDK にデータをプッシュします。
_externalPlayoutStreamId = [self.engine addExternalAudioStream:config];

PCM データをストリームにプッシュ

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) {
    // バッファーが満杯です。
    sleep(20);
} else if(ret < 0) {
    /* 例外が発生しました。パラメーターと公開状態を確認してください。 */
}

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) {
    // バッファーが満杯です。
    sleep(20);
} else if(ret < 0) {
    /* 例外が発生しました。パラメーターと公開状態を確認してください。 */
}

外部音声ストリームの削除

Android

mAliRtcEngine.removeExternalAudioStream(audioStreamID);

iOS

[self.engine removeExternalAudioStream:_externalPublishStreamId];

よくある質問

  1. startAudioAccompany を使用して伴奏を再生する際、リモートユーザーのみが伴奏を聴けるようにし、ローカルマイクの音声は送信しないようにするにはどうすればよいですか?

    伴奏の再生前または再生中に muteLocalMic メソッドを呼び出してマイクをミュートします。この設定により、リモートユーザーは伴奏のみを聴くことができます。