畅直播
  • iOS
  • Android : Java
  • macOS
  • Windows
  • Web
  • Flutter
  • 产品简介
    • 概述
    • 发布日志
    • 基本概念
    • 产品优势
    • 应用场景
    • 限制说明
    • 升级指南
  • 计费说明
  • 下载
  • 快速开始
  • 直播推流
  • 直播拉流
  • 通信能力
  • 房间能力
  • 音频能力
  • 视频能力
  • 直播能力
  • 其他能力
  • 最佳实践
  • 客户端 API
  • 服务端 API
  • 常用错误码
  • 常见问题
  • 文档中心
  • 畅直播
  • 其他能力
  • 媒体播放器

媒体播放器

更新时间:2024-01-02 18:48

功能简介

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

应用场景

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

支持格式

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

支持协议

支持 HTTP 和 HTTPS 协议。

示例源码下载

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

相关源码请查看 “/ZegoExpressExample/Others/src/main/java/im/zego/others/mediaplayer” 目录下的文件。

前提条件

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

使用步骤

1 创建媒体播放器

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

  • 调用示例

    // 创建媒体播放器实例对象, 目前最多支持创建 4 个实例,超过后将返回 null
    ZegoMediaPlayer mediaplayer = mEngine.createMediaPlayer();
    if (mediaplayer != null) {
        Log.d(TAG, "createMediaPlayer create sucess");
    } else {
        Log.d(TAG, "createMediaPlayer create fail");
    }

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

播放器事件设置回调

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

  • 调用示例

    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());
    

3 加载媒体文件

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

如果正在播放之前加载的媒体文件,请先调用 stop 接口停止播放,然后再调用 loadResource 接口加载媒体资源,否则无法加载成功。

  • 调用示例

    /**
     * 加载媒体资源
     *
     * 可传本地资源的绝对路径或者网络资源的 URL
     * @param path 本地资源路径或网络资源的 URL
     * @param 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);
            }
        }
    });
    /**
     * 加载二进制音频数据
     *
     * @param mediaData 二进制音频数据
     * @param startPosition 指定开始播放的进度,单位毫秒
     * @param callback 资源加载结果的通知
     */
    zegoMediaplayer.loadResourceFromMediaData(data, position, 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 播放控制

播放状态控制

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

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

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

  • 调用示例

    // 设置是否重复播放
    mediaplayer.enableRepeat(true);
    // 开始播放,播放前需要先加载资源
    mediaplayer.start();
    // 暂停播放
    mediaplayer.pause();
    // 恢复播放
    mediaplayer.resume();
    // 停止播放
    mediaplayer.stop();

播放进度控制

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

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

通过 seekTo 接口来调整进度。

  • 调用示例

    // 设置播放进度回调间隔, 单位为毫秒, 可通过此接口控制 [onMediaPlayerPlayingProgress] 的回调频率
    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);
            }
        }
    });

播放速度控制

加载资源完成后,用户可通过 setPlaySpeed 来设置当前播放速度。

  • 调用示例

    // 设置 2 倍速播放, 必须在加载资源完成后才能调用, 播放速度范围为 0.5 ~ 2.0,默认为 1.0
    mediaplayer.setPlaySpeed(2.0);

播放器音频控制

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

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

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

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

如果要使用混音能力,必须要 设置麦克风权限,如果您不希望录制麦克风的声音,可以通过 muteMicrophone 静音麦克风。

int playVolume = mediaplayer.getPlayVolume();
mediaplayer.setPlayVolume(playVolume / 2);
int publishVolume = mediaPlayer.getPublishVolume();
mediaPlayer.setPublishVolume(publishVolume);
mediaplayer.muteLocal(true);
mediaplayer.enableAux(true);

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

  • 调用示例

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

播放器视频控制

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

  • 调用示例

    // 设置播放器播放视频的视图
    // 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);// 第二个参数一般应指定为平台默认的视频帧格式

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

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

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

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

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

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

变声

处理类似于 KTV 中对伴奏升降调等场景时,可以调用媒体播放器的 setVoiceChangerParam 接口来实现变声功能。开发者可通过 ZegoVoiceChangerParam 对象中的音高参数 “pitch” 设置变声效果,该参数取值范围为 [-12.0, 12.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);

5 销毁媒体播放器

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

  • 调用示例

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

常见问题

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

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

本篇目录