媒体播放器组件(MediaPlayer Kit)是一款功能强大的播放器,支持播放本地或在线的媒体资源。通过该播放器,你可以本地播放媒体资源,或将媒体资源同步分享给声网频道内的远端用户观看/收听。
声网在 GitHub 上提供开源的 MediaPlayer 示例项目供你参考。
如果你的网络环境部署了防火墙,请根据应用企业防火墙限制打开相关端口。
分享媒体资源到远端时,还需有效的声网账户(免费注册)。
参考以下步骤创建一个 Windows 项目。
在解决方案资源管理器窗口中,右击项目名称并点击属性进行以下配置,配置完成后点击确定。
版本要求:2.4.0 或更高版本。
集成步骤:参考集成 Native SDK。
集成步骤:
集成 MediaPlayer Kit 后,参考如下步骤实现本地播放功能。
初始化媒体播放器
调用 createAgoraMediaPlayer
方法创建 IMediaPlayer
实例。
如需同时播放不同的媒体资源,你可以创建多个实例。
调用 initialize
方法初始化媒体播放器。
设置日志
日志文件包含媒体播放器组件运行时产生的所有日志。日志文件的默认输出地址为 C:/Users/{user_name}/AppData/Local/Agora/{project_name}
。调用以下方法可以对日志文件进行如下设置:
IMediaPlayer
类的 setLogFile
方法设置日志文件的输出地址。IMediaPlayer
类的 setLogFilter
方法设置输出日志的过滤等级。注册一个播放器观测器对象
IMediaPlayerObserver
接口,并实例化 IMediaPlayerObserver
对象。IMediaPlayer
类的 registerPlayerObserver
方法注册一个播放器的观测器对象,监听以下播放事件:onPositionChanged
,报告当前播放进度onPlayerStateChanged
,报告播放状态改变onPlayerEvent
,报告播放器事件onMetadata
,报告媒体附属信息(metadata)的接收通过监听这些事件,你可以更好地掌握播放过程,并使用自定义格式数据(媒体附属信息)。如果播放发生异常,你可以根据这些事件排查问题。
(可选)注册一个音频观测器对象
IAudioFrameObserver
接口,并实例化 IAudioFrameObserver
对象。IMediaPlayer
类的 registerAudioFrameObserver
方法注册一个音频观测器对象,监听每帧音频帧的接收事件。获取到 AudioPcmFrame
后你可以对音频进行录制。(可选)注册一个视频观测器对象
IVideoFrameObserver
接口,并实例化 IVideoFrameObserver
对象。IMediaPlayer
类的 registerVideoFrameObserver
方法注册一个视频观测器对象,监听每帧视频帧的接收事件。获取到 VideoFrame
后你可以对视频进行录制和截图。准备播放
调用 IMediaPlayer
类的 setView
方法设置播放器的渲染视图。
调用 IMediaPlayer
类的 setRenderMode
方法设置播放器视图的渲染模式。
调用 IMediaPlayer
类的 open
方法打开媒体资源。媒体资源路径可以为网络路径或本地路径,支持绝对路径和相对路径。
请收到
onPlayerStateChanged
回调报告播放状态为PLAYER_STATE_OPEN_COMPLETED(2)
后再进行下一步操作。
调用 IMediaPlayer
类的 play
方法本地播放该媒体资源。
调节播放设置
调用 AgoraMediaPlayerKit
接口的其他方法,你可以实现如下播放设置:
结束播放
调用 IMediaPlayer
类的 stop
方法停止播放。
调用 IMediaPlayer
类的 unregisterAuidoFrameObserver
方法取消观测音频帧。
如果你没有注册音频观测器,请略过此步。
调用 IMediaPlayer
类的 unregisterVideoFrameObserver
方法取消观测视频帧。
如果你没有注册视频观测器,请略过此步。
调用 IMediaPlayer
类的 unregisterPlayerObserver
方法取消观测播放器事件。
调用 IMediaPlayer
类的 release
方法释放 IMediaPlayer
资源。
示例代码
class CPlayerSimpleDemo : public CWnd, public agora::rtc::IMediaPlayerObserver {
public:
DECLARE_MESSAGE_MAP()
CPlayerSimpleDemo() : media_player_( nullptr )
{
}
~CPlayerSimpleDemo()
{
if ( media_player_ )
{
media_player_->Release();
media_player_ = nullptr;
}
}
// IMediaPlayerObserver
virtual void onPlayerStateChanged( const IMediaPlayer::PLAYER_STATE state,
const IMediaPlayer::PLAYER_ERROR ec ) override
{
switch ( state )
{
case IMediaPlayer::PLAYER_STATE_OPEN_COMPLETE:
media_player_->play();
break;
case IMediaPlayer::PLAYER_STATE_FAILED:
media_player_->stop();
break;
case IMediaPlayer::PLAYER_STATE_PLAYBACKCOMPLETED:
media_player_->stop();
break;
default:
break;
}
}
virtual void onPositionChanged( const int64_t position ) override
{
}
virtual void onMetaData( void* data, int length ) override
{
}
virtual void onPlayerEvent( const IMediaPlayer::PLAYER_EVENT event ) override
{
}
afx_msg int OnCreate( LPCREATESTRUCT lpCreateStruct )
{
if ( CWnd::OnCreate( lpCreateStruct ) == -1 )
return(-1);
media_player_ = createAgoraMediaPlayer();
if ( media_player_ )
{
media_player_->registerPlayerObserver( this );
media_player_->setView( m_hWnd );
media_player_->open( "http://tb-video.bdstatic.com/tieba-smallvideo/68_20df3a646ab5357464cd819ea987763a.mp4" );
}
return(0);
}
private:
agora::rtc::IMediaPlayer* media_player_;
};
集成 MediaPlayer Kit、声网 Native SDK 和 RtcChannelPublishPlugin 后,参考如下步骤将本地用户使用播放器播放的媒体资源分享给声网频道内的远端用户。
实例化
attachPlayerToRtc
方法将播放器和声网频道捆绑。播放器完成准备工作
参考本地播放媒体资源,注册播放器、音频和视频的观测器对象,完成准备播放。
请收到
onPlayerStateChanged
回调报告播放状态为PLAYER_STATE_PLAYING (3)
后再进行下一步操作。
本地用户加入频道
参考 RTC 快速开始,实现本地用户以主播身份加入声网直播频道:
setChannelProfile
方法设置频道场景为直播。setClientRole
方法设置本地用户角色为主播。enableVideo
方法开启视频模块。joinChannel
方法使本地用户加入频道。请收到
onJoinChannelSuccess
回调后再进行下一步操作。
开始分享
adjustPlayoutSignalVolume
方法设置播放音量为 0
,再调用 IMediaPlayer
类的 mute(true)
。publishVideo
/publishAudio
方法将播放的视频/音频流分享给声网频道内远端用户。adjustPublishSignalVolume
方法调节远端播放音量。取消分享
unpublishVideo
/unpublishAudio
方法取消分享该视频/音频流。detachPlayerFromRtc
方法将播放器和声网频道解绑。leaveChannel
使本地用户取消分享媒体流,否则本地用户重新加入频道时可能会出现以下问题:
示例代码
AgoraRtcChannelPublishHelper *agora_rtc_channel_publish_helper_= new AgoraRtcChannelPublishHelper()
virtual void onPlayerStateChanged( const IMediaPlayer::PLAYER_STATE state,
const IMediaPlayer::PLAYER_ERROR ec ) override
{
switch ( state )
{
case IMediaPlayer::PLAYER_STATE_OPEN_COMPLETE:
agora_rtc_channel_publish_helper_->attachPlayerToRtc(rtc_engine_, media_player_);
agora_rtc_channel_publish_helper_->publishAudio();
agora_rtc_channel_publish_helper_->publishVideo();
break;
case IMediaPlayer::PLAYER_STATE_FAILED:
media_player_->stop();
break;
case IMediaPlayer::PLAYER_STATE_PLAYBACKCOMPLETED:
media_player_->stop();
break;
default:
break;
}
}
为避免播放过程中,本地用户切换语音路由后,新的语音路由无声的问题,声网建议你进行如下操作:
joinChannel
后调用 enumeratePlaybackDevices
方法获取蓝牙设备的 deviceId
。setPlaybackDevice
方法并传入 deviceId
,设置通过该蓝牙设备播放。详见 API 文档