外部音频导入
在某些特殊的场景中,单纯的麦克风输入可能不能很好地满足大多数需求。对于这些场景,SDK 提供了 外部音频导入 这种方式来允许您将自定义的音频(在线音乐/本地音乐/音频 Buffer)作为输入源来获取可用于发布和播放的媒体对象。
如果您希望同时发布麦克风人声和外部导入的音频,音乐混音 可能是一个更好的选择。它提供了更为上层的 API 方便您完成背景音乐和音效等场景的集成。
获取外部导入的音频媒体对象
我们之前在 采集和 Track 管理 一章中介绍了采集麦克风媒体对象的方法。实际上外部导入的用法和采集麦克风差不多,只要稍微修改下 getLocalTracks 的配置就行。
import * as QNRTC from "pili-rtc-web";
const externalAudioTrack = await QNRTC.deviceManager.getLocalTracks({
audio: {
enabled: true,
source: "http://pkeamo5ex.bkt.clouddn.com/alice.mp3",
},
});
注意这里的 source
参数,当我们在 audio
字段下提供了 source
之后,SDK 就不会从麦克风中采集媒体了,而是从用户提供的 source
下获取媒体源。在这里的例子中,source
提供了一个在线地址,SDK 会尝试从这个在线音乐中获取媒体源。
如何获取本地文件对象
除了在线地址,source
还支持传入 本地文件 或者 音频 Buffer。下面演示了如何通过用户本地的文件来实现外部音频导入
<!-- 首先我们在 HTML 中准备一个 type 为 file 的 input 元素 -->
<label for="file_input">选择音乐文件</label>
<input id="file_input" type="file" accept=".mp3 .ogg"></input>
// 上面的 html 会在页面上渲染一个可以弹出系统级文件选择弹窗的按钮
// 我们注册相应的事件捕获用户选择本地文件的动作就好
const input = document.getElementById("file_input");
input.addEventListener("change", async (e) => {
// 获取当前用户选择的文件,这里是一个文件数组,因为有可能有多选的情况
const files = input.files;
// 我们将第一个文件作为用户选择的文件
const targetFile = files[0];
// 如果文件存在(因为用户可能没有选择
// targetFile 就是 SDK 所需要的本地文件对象,在混音的场景下也会用到
// 这里我们演示用这个文件进行外部音频导入
if (targetFile) {
const externalAudioTrack = await QNRTC.deviceManager.getLocalTracks({
audio: {
enabled: true,
source: targetFile,
}
});
}
});
操作外部导入的音频媒体对象
通过以上的一些步骤,我们已经获取到了包含外部音频源的 externalAudioTrack
对象。这个对象相对于普通的媒体对象(Track)来说有些特殊,因为其输入源的特殊性,SDK 为它提供了一些普通媒体对象没有的方法。
所以对于外部音频媒体对象,我们单独封装了一个类 AudioSourceTrack。这个类继承于我们通用的媒体对象 Track, 除了一些额外的方法以外,使用上和普通的 Track
对象并无区别,一样可以直接用来发布。
关于外部导入的音频媒体对象 AudioSourceTrack 的详细介绍,可以点击蓝字查看其 API 文档,这里简单介绍一下主要的操作流程。
播放外部导入的音频媒体对象
如果您直接像之前采集的步骤中一样调用 play
方法来播放这个 externalAudioTrack
对象,会发现听不见声音。这是因为外部导入的音频媒体对象的播放分为 2 个过程:
- 开始在内部处理导入的媒体数据
- 将处理好(解码后)的媒体数据绑定到一个
<audio>
元素上使得用户能听到输出的声音
可以看出,如果只调用 play
而没有开始处理导入的媒体数据,<audio>
元素就永远获得不了输入,从而听不见声音。想做到真正的播放,可以通过以下方法来实现:
// 开始处理媒体源数据
externalAudioTrack.startAudioSource();
// 将 `<audio>` 元素渲染到页面上,让用户听到声音
externalAudioTrack.play(document.body);
您可能会问为什么 SDK 要多此一举把这个步骤拆成 2 个方法,其实这是为了能够更灵活地控制整个播放过程。这样一来,只要我们暂停处理媒体数据,播放也会相应地被暂停,停止处理媒体数据,播放也会相应地被停止。
暂停/恢复/停止
// 暂停处理媒体源数据
externalAudioTrack.pauseAudioSource();
// 恢复处理媒体源数据
externalAudioTrack.resumeAudioSource();
// 停止处理媒体源数据
externalAudioTrack.stopAudioSource();
时间控制
// 获取当前的播放时间
externalAudioTrack.getCurrentTime();
// 设置当前的播放时间
externalAudioTrack.setCurrentTime(60);
// 获取媒体源的总时长
externalAudioTrack.getDuration();
以上时间控制的单位均为 秒
跟踪外部音频的播放状态
因为外部媒体源的特殊性,很多场景下需要能够动态获取当前媒体源的处理状态(常见的比如在线的音频是否正在加载)。SDK 提供了相应的事件来完成这个需求,通过 audio-state-change 我们可以获取当前处理状态的变化,具体状态列表可以点蓝字到 API 文档中详细查看。