媒体播放器
媒体播放器是 RTC SDK 内置的一个播放器,支持播放多种格式的媒体资源。本文介绍如何调用媒体播放器相关的 API 播放本地或在线媒体资源,并将媒体资源分享给声网频道内的远端用户观看或收听。
前提条件
在进行操作之前,请确保你已经在项目中实现了基本的实时音视频功能。有关详细信息,请参考实现音视频互动。
实现方法
参考如下步骤,在你的项目中使用媒体播放器:
创建媒体播放器对象
初始化 IRtcEngine
后,调用 createMediaPlayer
创建一个 IMediaPlayer
对象。
如果你需要创建多个媒体播放器对象,可以多次调用 CreateMediaPlayer
。
MediaPlayer = RtcEngine.CreateMediaPlayer();
if (MediaPlayer == null)
{
this.Log.UpdateLog("CreateMediaPlayer failed!");
return;
}
注册回调事件并实现回调
-
调用
IMediaPlayer
类下的InitEventHandler
方法添加媒体播放器的回调事件。C#MpkEventHandler handler = new MpkEventHandler(this);
MediaPlayer.InitEventHandler(handler);
this.Log.UpdateLog("playerId id: " + MediaPlayer.GetId()); -
根据你的需求,实现媒体播放器观测器的回调。
C#class MpkEventHandler : IMediaPlayerSourceObserver
{ // 报告播放器状态改变
public override void OnPlayerSourceStateChanged(MEDIA_PLAYER_STATE state, MEDIA_PLAYER_REASON reason)
{
}
// 报告播放器的事件
public override void OnPlayerEvent(MEDIA_PLAYER_EVENT @event, Int64 elapsedTime, string message)
{
Debug.Log(string.Format("OnPlayerEvent state: {0}", @event));
}
// 报告预加载媒体资源的事件
public override void OnPreloadEvent(string src, PLAYER_PRELOAD_EVENT @event)
{
Debug.Log(string.Format("OnPreloadEvent src: {0}, @event: {1}", src, @event));
}
// 报告当前媒体资源的播放进度
public override void OnPositionChanged(long positionMs, long timestampMs)
{
}
}
设置视频渲染窗口
如果你需要播放视频资源,在媒体资源打开后,设置视频渲染。当播放器停止播放时,销毁对应的视频视图。在渲染视图时,你可以通过 GetId
获取媒体播放器的 ID,并需要将 VIDEO_SOURCE_TYPE
设为 VIDEO_SOURCE_MEDIA_PLAYER
。
// 报告播放器状态改变
public override void OnPlayerSourceStateChanged(MEDIA_PLAYER_STATE state, MEDIA_PLAYER_REASON reason)
{
Debug.Log(string.Format(
"OnPlayerSourceStateChanged state: {0}, ec: {1}, playId: {2}", state, reason, _sample.MediaPlayer.GetId()));
Debug.Log("OnPlayerSourceStateChanged");
if (state == MEDIA_PLAYER_STATE.PLAYER_STATE_OPEN_COMPLETED)
{
// 成功打开媒体资源后,创建一个视图用于显示媒体播放器的视频流
MakeVideoView((uint)_sample.MediaPlayer.GetId(), "", VIDEO_SOURCE_TYPE.VIDEO_SOURCE_MEDIA_PLAYER);
}
else if (state == MEDIA_PLAYER_STATE.PLAYER_STATE_STOPPED)
{
// 播放停止后,销毁视频视图
DestroyVideoView((uint)_sample.MediaPlayer.GetId());
}
}
调用 SetForUser
设置视频显示,调用 SetEnable
开始视频渲染。
// 创建一个视频视图
static void MakeVideoView(uint uid, string channelId = "", VIDEO_SOURCE_TYPE videoSourceType = VIDEO_SOURCE_TYPE.VIDEO_SOURCE_CAMERA)
{
var go = GameObject.Find(uid.ToString());
if (!ReferenceEquals(go, null))
{
return;
}
// 创建一个新的 GameObject 用于渲染视频
var videoSurface = MakeImageSurface(uid.ToString());
if (ReferenceEquals(videoSurface, null)) return;
// 设置视频显示
videoSurface.SetForUser(uid, channelId, videoSourceType);
// 开始视频渲染
videoSurface.SetEnable(true);
// Texture 的宽高发生改变回调
videoSurface.OnTextureSizeModify += (int width, int height) =>
{
var transform = videoSurface.GetComponent<RectTransform>();
if (transform)
{
// 如果在 RawImage 中渲染,只需设置 RawImage 的大小
transform.sizeDelta = new Vector2(width / 2, height / 2);
transform.localScale = Vector3.one;
}
else
{
// 如果在 MeshRenderer 中渲染,只需设置 MeshRenderer 的本地大小
float scale = (float)height / (float)width;
videoSurface.transform.localScale = new Vector3(-1, 1, scale);
}
Debug.Log("OnTextureSizeModify: " + width + " " + height);
};
}
// 销毁视频视图
static void DestroyVideoView(uint uid)
{
var go = GameObject.Find(uid.ToString());
if (!ReferenceEquals(go, null))
{
Destroy(go);
}
}
// 创建一个新的视频视图,包含一个 RawImage 组件,用于显示视频
private static VideoSurface MakeImageSurface(string goName)
{
// 创建一个新的 GameObject
GameObject go = new GameObject();
go.name = goName;
// 添加 RawImage 组件,用于渲染视频
go.AddComponent<RawImage>();
go.AddComponent<UIElementDrag>();
var canvas = GameObject.Find("VideoCanvas");
if (canvas != null)
{
go.transform.parent = canvas.transform;
Debug.Log("add video view");
}
else
{
Debug.Log("Canvas is null video view");
}
// 设置 GameObject 的变换
go.transform.Rotate(0f, 0.0f, 180.0f);
go.transform.localPosition = Vector3.zero;
go.transform.localScale = new Vector3(4.5f, 3f, 1f);
// 添加 VideoSurface 组件
var videoSurface = go.AddComponent<VideoSurface>();
return videoSurface;
}
打开媒体资源
调用 Open
打开本地或在线媒体文件并设置起始播放位置。支持打开的媒体资源格式见支持的格式。
public void OnOpenButtonPress()
{
var ret = MediaPlayer.Open("Your File Path", 0);
Debug.Log("Open returns: " + ret);
}
声网还提供 OpenWithMediaSource
方法打开媒体资源,同时可以进行播放设置,例如设置是否开启自动播放、实时缓存等功能。
发布媒体播放器的音视频流
调用 JoinChannel
[2/2] 加入频道时,在 ChannelMediaOptions
中进行如下设置:
- 设置用户角色为主播(
CLIENT_ROLE_BROADCASTER
)。 - 将
autoSubscribeAudio
和autoSubscribeVideo
设为true
,自动订阅所有音视频流。 - 将
publishMediaPlayerAudioTrack
和publishMediaPlayerVideoTrack
设为true
,发布媒体播放器的音视频流。 - 将
publishMediaPlayerId
设为你的媒体播放器的 ID。 - 将
enableAudioRecordingOrPlayout
设为true
,开启音频播放。
ChannelMediaOptions options = new ChannelMediaOptions();
// 自动订阅远端的音频流
options.autoSubscribeAudio.SetValue(true);
// 自动订阅远端的视频流
options.autoSubscribeVideo.SetValue(true);
options.publishCustomAudioTrack.SetValue(false);
options.publishCameraTrack.SetValue(false);
// 设置发布视频播放器的音频流
options.publishMediaPlayerAudioTrack.SetValue(true);
// 设置发布视频播放器的视频流
options.publishMediaPlayerVideoTrack.SetValue(true);
// 待发布的媒体播放器的 ID
options.publishMediaPlayerId.SetValue(MediaPlayer.GetId());
// 开启音频录制或播放
options.enableAudioRecordingOrPlayout.SetValue(true);
// 设置用户角色为主播
options.clientRoleType.SetValue(CLIENT_ROLE_TYPE.CLIENT_ROLE_BROADCASTER);
// 加入频道
var ret = RtcEngine.JoinChannel(_token, _channelName, 0, options);
this.Log.UpdateLog("RtcEngineController JoinChannel_MPK returns: " + ret);
播放控制
本节介绍如何实现播放控制,包括暂停、恢复播放、停止播放等功能。
播放
调用 Play
方法打开本地或在线的媒体资源。
- 如果你通过
Open
打开媒体资源,你需要在收到OnPlayerSourceStateChanged
回调报告状态为PLAYER_STATE_OPEN_COMPLETED
后再调用Play
进行播放。 - 如果你通过
OpenWithMediaSource
打开媒体资源,且autoPlay
为true
时,媒体资源打开后会自动播放,无需再额外调用Play
方法。
public void OnPlayButtonPress()
{
var ret = MediaPlayer.Play();
Debug.Log("Play return" + ret);
}
循环播放
如果你需要循环播放,可以调用 SetLoopCount
方法并通过 loopCount
参数设置循环播放的次数,默认为 0
,表示不循环播放。如需无限循环播放,将该参数设为 -1
。
public void OnPlayButtonPress()
{
if (this.IsLoop())
{
MediaPlayer.SetLoopCount(-1);
}
else
{
MediaPlayer.SetLoopCount(0);
}
var ret = MediaPlayer.Play();
this.Log.UpdateLog("Play return" + ret);
}
定位指定位置播放
如果你需要定位到媒体资源的指定位置再播放,可以调用 Seek
方法定位到指定位置。
- 请确保在成功打开媒体文件后(即收到
OnPlayerSourceStateChanged
回调报告状态为PLAYER_STATE_OPEN_COMPLETED
)再调用Seek
。成功调用后,媒体播放器会自动从指定位置开始播放,并报告状态为PLAYER_STATE_PLAYING
。 - 如果你在暂停播放的情况下调用
Seek
,成功调用后,媒体资源仍然会是暂停播放的状态。如需播放,请调用Resume
或Play
。
设置播放速度
调用 SetPlaybackSpeed
方法来设置当前媒体文件的播放速度。
public void OnSetPlaybackSpeedButtonPress()
{
var ret = MediaPlayer.SetPlaybackSpeed(2);
this.Log.UpdateLog("SetPlaybackSpeed return" + ret);
}
暂停播放
调用 Pause
方法暂停当前播放。
public void OnPauseButtonPress()
{
var ret = MediaPlayer.Pause();
this.Log.UpdateLog("Pause return" + ret);
}
恢复播放
暂停播放后,如需恢复播放,调用 Resume
方法。
public void OnResumeButtonPress()
{
var ret = MediaPlayer.Resume()
this.Log.UpdateLog("Resume returns: " + ret);
}
停止播放
调用 Stop
方法停止播放。停止播放后,如果你需要再次播放,需要重新打开该媒体资源。
public void OnStopButtonPress()
{
var ret = MediaPlayer.Stop();
this.Log.UpdateLog("Stop return" + ret);
}
调整音量
如果你需要调整媒体播放器本地播放的音量,调用 AdjustPlayoutVolume
。如果要调整所播放的媒体资源发布到远端的音量,调用 AdjustPublishSignalVolume
。
var ret = MediaPlayer.AdjustPlayoutVolume(30);
this.Log.UpdateLog("AdjustPlayoutVolume return" + ret);
ret = MediaPlayer.AdjustPublishSignalVolume(50);
this.Log.UpdateLog("AdjustPublishSignalVolume return" + ret);
预加载媒体资源
如果你需要连续播放多个不同的媒体资源,可以预先加载待播放的媒体资源以保证资源切换时的观众体验。
-
调用
PreloadSrc
预加载媒体资源。如需加载多个资源,你可以多次调用该方法。预加载的相关事件可以通过监听OnPreloadEvent
回调得知。C#public void OnPreloadSrcButtonClick()
{
var nRet = MediaPlayer.PreloadSrc(PRELOAD_URL, 0);
this.Log.UpdateLog("PreloadSrc: " + nRet);
} -
调用
PlayPreloadedSrc
播放预加载的媒体资源。调用该方法后,如果你收到OnPlayerStateChanged
回调报告状态PLAYER_STATE_PLAYING
,则表示播放成功。C#public void OnPlayPreloadButtonClick()
{
var nRet = MediaPlayer.PlayPreloadedSrc(PRELOAD_URL);
this.Log.UpdateLog("PlayPreloadedSrc: " + nRet);
} -
如果不再需要已加载的媒体资源,可以调用
UnloadSrc
释放预加载的资源。C#var nRet = MediaPlayer.UnloadSrc(PRELOAD_URL);
this.Log.UpdateLog("UnloadSrc: " + nRet);
离开频道
参考下列步骤离开频道:
- 调用
DestroyMediaPlayer
销毁媒体播放器对象。 - 调用
InitEventHandler
取消注册播放器事件观测器。 - 调用
LeaveChannel
离开频道。 - 调用
Dispose
销毁IRtcEngine
对象并释放 SDK 使用的资源。
public void OnLeaveChannelButtonPress()
{
if (RtcEngine == null) return;
// 销毁媒体播放器对象
if (MediaPlayer != null) RtcEngine.DestroyMediaPlayer(MediaPlayer);
// 取消注册播放器事件观测器
RtcEngine.InitEventHandler(null);
// 离开频道
RtcEngine.LeaveChannel();
// 销毁引擎并释放资源
RtcEngine.Dispose();
RtcEngine = null;
MediaPlayer = null;
}
参考信息
示例项目
声网提供了开源的音视频互动示例项目供你参考,你可以前往下载或查看其中的源代码。
支持的格式
声网的媒体播放器支持下列格式及协议:
视频编码格式
- H.263、H.264、H.265、MPEG4、MPEG2、RMVB、Theora、VP3、VP8、AVS、WMV
音频编码格式
- WAV、MP2、MP3、AAC、OPUS、FLAC、Vorbis、AMR-NB、AMR-WB、WMA v1、WMA v2
容器格式
- WAV、FLAC、OGG、MOV、ASF、FLV、PM3、MP4、MPEG-TS、Matroska (MKV)、AVI、ASS、CONCAT、DTS、AVS
支持的协议
- HTTP、HTTPS、RTMP、HLS、RTP、RTSP