实时语音
  • 平台类型
  • 框架 / 引擎
  • iOS
  • Android
  • macOS
  • Windows
  • Linux
  • Web
  • 小程序

媒体播放器

更新时间:2021-05-12 10:42

1 功能简介

媒体播放器组件提供播放音视频媒体文件的能力,并且支持将播放的媒体文件的音画数据推流出去。

1.1 应用场景

  • 播放测试音频:可以使用媒体播放器播放测试音频,验证音频播放设备是否工作正常。
  • 播放背景音乐:使用媒体播放器播放音乐并混在流中推送出去,让远端听到背景音乐。
  • 播放视频文件:结合自定义视频采集功能将媒体资源的视频数据推送出去,远端可拉流观看。

1.2 支持格式

媒体播放器支持 MP3、MP4、FLV、WAV、AAC、M3U8 等格式文件。

媒体播放器默认支持格式为:MP3、MP4、FLV、WAV、AAC。如需支持其它格式,请联系 ZEGO 技术支持。

1.3 支持协议

支持 HTTP 和 HTTPS 协议。

2 示例源码下载

请参考 下载示例源码 获取源码。

相关源码请查看 “/ZegoExpressExample/Mediaplayer” 目录下的文件。

3 前提条件

在实现媒体播放器功能之前,请确保:

4 使用步骤

4.1 创建媒体播放器

调用 “ZegoExpressEngine” 的成员方法 createMediaPlayer 接口以创建媒体播放器实例。一个媒体播放器实例只能播放一个音视频,引擎同一时间最多支持创建 4 个播放器实例,以达到同时播放多个媒体资源的效果。若当前已存在 4 个播放器实例,再次调用创建播放器接口将返回 null

  • 接口原型

    /**
     * 创建媒体播放器实例对象
     *
     * 目前最多支持创建 4 个实例,超过后将返回 null
     * @return 媒体播放器实例,超过最大数量限制后将返回 null
     */
    public ZegoMediaPlayer createMediaPlayer();
  • 调用示例

    ZegoMediaplayer mediaplayer = mEngine.createMediaPlayer();
    if (mediaplayer != null) {
        Log.d(TAG, "createMediaPlayer create sucess");
    } else {
        Log.d(TAG, "createMediaPlayer create fail");
    }

4.2 (可选)为播放器设置事件回调

播放器事件设置回调

调用媒体播放器的 setEventHandler 接口为播放器设置事件回调,以接收“播放器状态改变”、“播放进度改变”、“播放器网络状态更新”等通知。

  • 接口原型

    public abstract class IZegoMediaPlayerEventHandler {
    
        public void onMediaPlayerStateUpdate(ZegoMediaPlayer mediaPlayer, ZegoMediaPlayerState state, int errorCode){
    
        }
    
        public void onMediaPlayerNetworkEvent(ZegoMediaPlayer mediaPlayer, ZegoMediaPlayerNetworkEvent networkEvent){
    
        }
    
        public void onMediaPlayerPlayingProgress(ZegoMediaPlayer mediaPlayer, long millisecond){
    
        }
    
    }
  • 调用示例

    public class MyIZegoMediaPlayerEventHandler extends IZegoMediaPlayerEventHandler {
    
        private static final String TAG = "MyIZegoExpressMediaplay";
    
        @Override
        public void onMediaPlayerStateUpdate(ZegoMediaPlayer mediaPlayer, ZegoMediaPlayerState state, int errorCode) {
            // 本回调在UI线程被回调, 开发者可以在此进行UI的变化, 例如播放按钮的变化
            Log.d(TAG, "onMediaPlayerStateUpdate: state = " + state.value() + ", errorCode = " + errorCode + ", zegoExpressMediaplayer = " + mediaPlayer);
        }
    
        @Override
        public void onMediaPlayerNetworkEvent(ZegoMediaPlayer mediaPlayer, ZegoMediaPlayerNetworkEvent networkEvent) {
            // 本回调在UI线程被回调, 开发者可以在此进行UI的变化, 例如网络不好的情况做友好的提示
            Log.d(TAG, "onMediaPlayerNetworkEvent: networkEvent = " + networkEvent.value() + ", zegoExpressMediaplayer = " + mediaPlayer);
        }
    
        @Override
        public void onMediaPlayerPlayingProgress(ZegoMediaPlayer mediaPlayer, long millisecond) {
            // 本回调在UI线程被回调, 开发者可以在此进行UI的变化, 例如进度条的变化
            Log.d(TAG, "onMediaPlayerPlayingProgress: millisecond = " + millisecond + ", zegoExpressMediaplayer = " + mediaPlayer);
        }
    }
    
    mediaplayer.setEventHandler(new MyIZegoMediaPlayerEventHandler());
    

4.3 加载媒体文件

调用媒体播放器的 loadResource 指定要播放的媒体资源,可以是本地资源的绝对路径,也可以是网络资源的 URL,如 “http://your.domain.com/your-movie.mp4”。用户可通过传入回调参数的方式获取加载文件的结果。

  • 接口原型

    /**
     * 加载媒体资源
     *
     * 可传本地资源的绝对路径或者网络资源的 URL
     * @param path 本地资源路径或网络资源的 URL
     * @param callback 资源加载结果的通知
     */
    public void loadResource(String path, IZegoMediaPlayerLoadResourceCallback callback);
  • 调用示例

    zegoMediaplayer.loadResource("sourcePath", new IZegoMediaPlayerLoadResourceCallback() {
        @Override
        public void onLoadResourceCallback(int errorcode) {
            // 本回调在UI线程被回调, 开发者可以在此进行UI的变化
            if(errorCode == 0){
                Log.d(TAG, "onLoadResourceCallback: success");
            } else {
                Log.d(TAG, "onLoadResourceCallback: errorcode = " + errorcode);
            }
        }
    });

4.4 播放控制

4.4.1 播放状态控制

调用 startpauseresumestop 来启停播放。一旦播放器的内部状态改变,onMediaplayerStateUpdate 回调将会被触发。

用户也可通过调用 getCurrentState 随时获取播放器的当前状态.

如果 enableRepeat 设置为 “true”,则播放器会在播放完文件后自动重播。

  • 接口原型

    /**
     * 是否重复播放
     * 
     * @param enable 重复播放标记
     */
    public void enableRepeat(boolean enable);
    
    /**
     * 开始播放
     *
     * 播放前需要先加载资源
     */
    public void start();
    
    /**
     * 暂停播放
     *
     */
    public void pause();
    
    /**
     * 恢复播放
     *
     */
    public void resume();
    
    /**
     * 停止播放
     *
     */
    public void stop();
  • 调用示例

    mediaplayer.enableRepeat(true);
    mediaplayer.start();
    mediaplayer.pause();
    mediaplayer.resume();
    mediaplayer.stop();

4.4.2 播放进度控制

播放文件的进度会通过 onMediaPlayerPlayingProgress 方法回调,默认触发回调的间隔是 1000 ms,可通过 setProgressInterval 更改此间隔。

用户也可通过 getCurrentProgress 来获取当前播放进度。

通过 seekTo 接口来调整进度。

  • 接口原型

    /**
     * 设置播放进度回调间隔
     *
     * 可通过此接口控制 [onMediaPlayerPlayingProgress] 的回调频率
     * @param millisecond 播放进度回调间隔时间,单位为毫秒
     */
    public void setProgressInterval(long millisecond);
    
    /**
     * 获取当前播放进度
     *
     */
    public long getCurrentProgress();
  • 调用示例

    mediaplayer.setProgressInterval(2000);
    long progress = mediaplayer.getCurrentProgress();
    mediaplayer.seekTo(mediaplayer.getTotalDuration() / 2, new IZegoMediaPlayerSeekToCallback(){
        @Override
        public void onSeekToTimeCallback(int errorcode) {
            // 本回调在UI线程被回调, 开发者可以在此进行UI的变化
            if(errorCode == 0){
                Log.d(TAG, "onSeekToTimeCallback: success");
            } else {
                Log.d(TAG, "onSeekToTimeCallback: errorcode = " + errorcode);
            }
        }
    });

4.4.3 播放器音频控制

通过 getPlayVolumesetPlayVolume 获取和控制播放音量。

通过 getPublishVolumesetPublishVolume 获取和控制推流音量。

调用 muteLocal 可以控制本地静音播放。

调用 enableAux 可以将文件的声音混入正在推的流中。

int playVolume = mediaplayer.getPlayVolume();
mediaplayer.setPlayVolume(playVolume / 2);
mediaplayer.muteLocal(true);
mediaplayer.enableAux(true);

如果想获取文件的音频数据,可通过 setAudioHandler 来设置音频帧回调。

  • 接口原型

    /**
     * 设置音频回调 handler
     *
     * 可以通过设置此回调将媒体播放器播放的媒体资源文件的音频数据抛出来
     * @param handler 媒体播放器的音频事件回调对象
     */
    public void setAudioHandler(IZegoMediaPlayerAudioHandler handler)
  • 调用示例

    // 播放器抛音频数据的回调
    mediaplayer.setAudioHandler(new IZegoMediaPlayerAudioHandler() {
        @Override
        public void onAudioFrame(ZegoMediaPlayer mediaPlayer, ByteBuffer data, int dataLength, ZegoAudioFrameParam param) {
            // 开发者可以在这个回调里对该抛出的音频帧数据进行处理, 例如进行本地存储、音效处理等
            Log.d(TAG, "onAudioFrame: buffer = " + data + ", zegoAudioFrame = " + dataLength);
        }
    });

4.4.4 播放器视频控制

当播放视频资源时,用 setPlayerCanvas 来设置视频的显示视图。

  • 接口原型

    /**
     * 设置播放器播放视频的视图
     *
     * @param canvas 视频渲染的画布对象
     */
    public void setPlayerCanvas(ZegoCanvas canvas);
  • 调用示例

    // textureView 为附着在UI布局上的 android.view.TextureView 实例
    mediaplayer.setPlayerCanvas(new ZegoCanvas(textureView));

如果想获取文件的视频数据,可通过 setVideoHandler 来设置视频帧回调。

  • 接口原型

    /**
     * 设置视频回调 handler
     *
     * 可以通过设置此回调将媒体播放器播放的媒体资源文件的视频数据抛出来
     * @param handler 媒体播放器的视频事件回调对象
     * @param format 视频数据的视频帧格式
     */
    public void setVideoHandler(IZegoMediaPlayerVideoHandler handler, ZegoVideoFrameFormat format);
  • 调用示例

    // 播放器抛视频数据的回调
    mediaplayer.setVideoHandler(new IZegoMediaPlayerVideoHandler(){
        @Override
        public void onVideoFrame(ZegoMediaPlayer mediaPlayer, ByteBuffer[] data, int[] dataLength, ZegoVideoFrameParam param) {
            // 开发者可以在这个回调里对该抛出的视频帧数据进行处理, 例如进行本地存储、视频图层混合等
            Log.d(TAG, "onVideoFrame");
        }
    }, ZegoVideoFrameFormat.Unknown);// 第二个参数一般应指定为平台默认的视频帧格式

4.4.5 将播放器播放的视频推流出去

  1. 将播放器的视频推流出去前,需要先通过 setVideoHandler 设置视频帧回调监听,用于获取 onVideoFrame 抛出的视频帧数据。

  2. 使用自定义方式采集视频,并将获取到的视频数据混入推流数据中,详细操作请参考 视频进阶 - 自定义视频采集

自定义采集数据时,建议开发者自行定义一个 “flag” 标记位:

  • 当触发 onStart 回调时将 “flag” 标记设置为 “True”,表示可以开始将自定义采集的视频数据发送给 SDK。
  • 当触发 onStop 回调时将 “flag” 标记设置为 “False”,表示需要停止发送采集的视频数据给 SDK。
  1. 开发者需要在 onVideoFrame 中添加对 “flag” 的判断逻辑,当 “flag” 设置为 “True” 时(即触发了 onStart 回调),调用 sendCustomVideoCaptureRawData 方法向 SDK 发送已获取的视频数据。

  2. 调用 startPublishingStream 开始推流,请参考 快速开始 - 实现流程 的 “2.3 推流”。

4.4.6 变声

处理类似于 KTV 中对伴奏升降调等场景时,可以调用媒体播放器的 setVoiceChangerParam 接口来实现变声功能。开发者可通过 ZegoVoiceChangerParam 对象中的音高参数 “pitch” 设置变声效果,该参数取值范围为 [-8.0, 8.0],值越大声音越尖锐,默认值为 “0.0”(即关闭变声器)。

ZegoVoiceChangerParam param = new ZegoVoiceChangerParam()
param.pitch = 8.0f;     /** 男声变童声 */
param.pitch = 4.0f;     /** 男声变女声 */
param.pitch = 6.0f;     /** 女声变童声 */
param.pitch = -3.0f;    /** 女声变男声 */
mediaplayer.setVoiceChangerParam(ZegoMediaPlayerAudioChannel.ALL, voiceChangerParam);

4.5 销毁媒体播放器

使用完播放器之后,需要及时的调用销毁接口以释放占用的资源。

  • 接口原型

    /**
     * 销毁媒体播放器实例对象
     *
     */
    public void destroyMediaPlayer(ZegoMediaPlayer mediaPlayer){
  • 调用示例

    mEngine.destroyMediaPlayer(mediaplayer);
    // 在调用接口销毁的时候, 为避免内存泄漏, 开发者须自己手动释放业务层所持有的引用
    mediaplayer = null;

5 API 参考列表

方法 描述
createMediaPlayer 创建媒体播放器
destroyMediaplayer 销毁媒体播放器
setVoiceChangerParam 设置变声参数

6 常见问题

  1. 如何在播放中途切换播放资源?

    先调用播放器的 stop 接口,然后重新调用 loadResource 接口加载新资源。