1、接口函数如下:两个函数的区别主要是一个是传入函数名,一个是传入数据流。
loop 表示要不要循环播放,format 表示采用的。
int StartPlayingFileLocally(int channel,
const char fileNameUTF8[1024],
bool loop = false,
FileFormats format = kFileFormatPcm16kHzFile,
float volumeScaling = 1.0,
int startPointMs = 0,
int stopPointMs = 0) override;
int StartPlayingFileLocally(int channel,
InStream* stream,
FileFormats format = kFileFormatPcm16kHzFile,
float volumeScaling = 1.0,
int startPointMs = 0,
int stopPointMs = 0) override;
2、channel 创建FilePlayer,并增加混音 additionalParticipant 角色,最终通过和远端通道一起混音播放。
int Channel::StartPlayingFileLocally(const char* fileName,
bool loop,
FileFormats format,
int startPosition,
float volumeScaling,
int stopPosition,
const CodecInst* codecInst) {
WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId, _channelId),
"Channel::StartPlayingFileLocally(fileNameUTF8[]=%s, loop=%d,"
" format=%d, volumeScaling=%5.3f, startPosition=%d, "
"stopPosition=%d)",
fileName, loop, format, volumeScaling, startPosition,
stopPosition);
if (channel_state_.Get().output_file_playing) {
_engineStatisticsPtr->SetLastError(
VE_ALREADY_PLAYING, kTraceError,
"StartPlayingFileLocally() is already playing");
return -1;
}
{
rtc::CritScope cs(&_fileCritSect);
if (output_file_player_) {
output_file_player_->RegisterModuleFileCallback(NULL);
output_file_player_.reset();
}
output_file_player_ = FilePlayer::CreateFilePlayer(
_outputFilePlayerId, (const FileFormats)format);
if (!output_file_player_) {
_engineStatisticsPtr->SetLastError(
VE_INVALID_ARGUMENT, kTraceError,
"StartPlayingFileLocally() filePlayer format is not correct");
return -1;
}
const uint32_t notificationTime(0);
if (output_file_player_->StartPlayingFile(
fileName, loop, startPosition, volumeScaling, notificationTime,
stopPosition, (const CodecInst*)codecInst) != 0) {
_engineStatisticsPtr->SetLastError(
VE_BAD_FILE, kTraceError,
"StartPlayingFile() failed to start file playout");
output_file_player_->StopPlayingFile();
output_file_player_.reset();
return -1;
}
output_file_player_->RegisterModuleFileCallback(this);
channel_state_.SetOutputFilePlaying(true);
}
if (RegisterFilePlayingToMixer() != 0)
return -1;
return 0;
}
3、fileplayer 类创建media file用来解析文件并把文件存放入audiocoder.
混音时从neteq 得到解码数据。