简介

ijkplayer是OpenHarmony环境下可用的一款基于FFmpeg的视频播放器。

演示

编译运行

1、通过IDE工具下载依赖SDK,Tools->SDK Manager->OpenHarmony SDK 把native选项勾上下载,API版本>=9

2、开发板选择RK3568,ROM下载地址. 选择开发板类型是rk3568,请使用最新的版本

3、使用git clone下载源码,不要直接通过gitee网页的方式下载

下载安装

ohpm install @ohos/ijkplayer

使用说明

import { IjkMediaPlayer } from "@ohos/ijkplayer";

import type { OnPreparedListener } from "@ohos/ijkplayer";

import type { OnVideoSizeChangedListener } from "@ohos/ijkplayer";

import type { OnCompletionListener } from "@ohos/ijkplayer";

import type { OnBufferingUpdateListener } from "@ohos/ijkplayer";

import type { OnErrorListener } from "@ohos/ijkplayer";

import type { OnInfoListener } from "@ohos/ijkplayer";

import type { OnSeekCompleteListener } from "@ohos/ijkplayer";

import { LogUtils } from "@ohos/ijkplayer";

在UI中配置XComponent控件

XComponent({

id: 'xcomponentId',

type: 'surface',

libraryname: 'ijkplayer_napi'

})

.onLoad((context) => {

this.initDelayPlay(context);

})

.onDestroy(() => {

})

.width('100%')

.aspectRatio(this.aspRatio)

播放

let mIjkMediaPlayer = IjkMediaPlayer.getInstance();

// 设置XComponent回调的context

mIjkMediaPlayer.setContext(this.mContext);

// 设置debug模式

mIjkMediaPlayer.setDebug(true);

// 初始化配置

mIjkMediaPlayer.native_setup();

// 设置视频源

mIjkMediaPlayer.setDataSource(url);

// 设置视频源http请求头

let headers = new Map([

["user_agent", "Mozilla/5.0 BiliDroid/7.30.0 (bbcallen@gmail.com)"],

["referer", "https://www.bilibili.com"]

]);

mIjkMediaPlayer.setDataSourceHeader(headers);

// 使用精确寻帧 例如,拖动播放后,会寻找最近的关键帧进行播放,很有可能关键帧的位置不是拖动后的位置,而是较前的位置.可以设置这个参数来解决问题

mIjkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "enable-accurate-seek", "1");

// 预读数据的缓冲区大小

mIjkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "max-buffer-size", "102400");

// 停止预读的最小帧数

mIjkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "min-frames", "100");

// 启动预加载

mIjkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "start-on-prepared", "1");

// 设置无缓冲,这是播放器的缓冲区,有数据就播放

mIjkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "packet-buffering", "0");

// 跳帧处理,放CPU处理较慢时,进行跳帧处理,保证播放流程,画面和声音同步

mIjkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "framedrop", "5");

// 最大缓冲cache是3s, 有时候网络波动,会突然在短时间内收到好几秒的数据

// 因此需要播放器丢包,才不会累积延时

// 这个和第三个参数packet-buffering无关。

mIjkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "max_cached_duration", "3000");

// 无限制收流

mIjkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "infbuf", "1");

// 屏幕常亮

mIjkMediaPlayer.setScreenOnWhilePlaying(true);

// 设置超时

mIjkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "timeout", "10000000");

mIjkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "connect_timeout", "10000000");

mIjkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "listen_timeout", "10000000");

mIjkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "addrinfo_timeout", "10000000");

mIjkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_FORMAT, "dns_cache_timeout", "10000000");

let mOnVideoSizeChangedListener: OnVideoSizeChangedListener = {

onVideoSizeChanged(width: number, height: number, sar_num: number, sar_den: number) {

that.aspRatio = width / height;

LogUtils.getInstance()

.LOGI("setOnVideoSizeChangedListener-->go:" + width + "," + height + "," + sar_num + "," + sar_den)

that.hideLoadIng();

}

}

mIjkMediaPlayer.setOnVideoSizeChangedListener(mOnVideoSizeChangedListener);

let mOnPreparedListener: OnPreparedListener = {

onPrepared() {

LogUtils.getInstance().LOGI("setOnPreparedListener-->go");

}

}

mIjkMediaPlayer.setOnPreparedListener(mOnPreparedListener);

let mOnCompletionListener: OnCompletionListener = {

onCompletion() {

LogUtils.getInstance().LOGI("OnCompletionListener-->go")

that.currentTime = that.stringForTime(mIjkMediaPlayer.getDuration());

that.progressValue = PROGRESS_MAX_VALUE;

that.stop();

}

}

mIjkMediaPlayer.setOnCompletionListener(mOnCompletionListener);

let mOnBufferingUpdateListener: OnBufferingUpdateListener = {

onBufferingUpdate(percent: number) {

LogUtils.getInstance().LOGI("OnBufferingUpdateListener-->go:" + percent)

}

}

mIjkMediaPlayer.setOnBufferingUpdateListener(mOnBufferingUpdateListener);

let mOnSeekCompleteListener: OnSeekCompleteListener = {

onSeekComplete() {

LogUtils.getInstance().LOGI("OnSeekCompleteListener-->go")

that.startPlayOrResumePlay();

}

}

mIjkMediaPlayer.setOnSeekCompleteListener(mOnSeekCompleteListener);

let mOnInfoListener: OnInfoListener = {

onInfo(what: number, extra: number) {

LogUtils.getInstance().LOGI("OnInfoListener-->go:" + what + "===" + extra)

}

}

mIjkMediaPlayer.setOnInfoListener(mOnInfoListener);

let mOnErrorListener: OnErrorListener = {

onError(what: number, extra: number) {

LogUtils.getInstance().LOGI("OnErrorListener-->go:" + what + "===" + extra)

that.hideLoadIng();

prompt.showToast({

message:"亲,视频播放异常,系统开小差咯"

});

}

}

mIjkMediaPlayer.setOnErrorListener(mOnErrorListener);

mIjkMediaPlayer.setMessageListener();

mIjkMediaPlayer.prepareAsync();

mIjkMediaPlayer.start();

暂停

mIjkMediaPlayer.pause();

停止

mIjkMediaPlayer.stop();

重置

mIjkMediaPlayer.reset();

释放

mIjkMediaPlayer.release();

快进、后退

mIjkMediaPlayer.seekTo(msec);

倍数播放

mIjkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "soundtouch", "1");

mIjkMediaPlayer.setSpeed("2f");

屏幕常亮

mIjkMediaPlayer.setScreenOnWhilePlaying(true);

循环播放

mIjkMediaPlayer.setLoopCount(true);

设置音量

mIjkMediaPlayer.setVolume(leftVolume, rightVolume);

接口说明

IjkMediaPlayer.getInstance()

接口名参数返回值说明setContextcontext: objectvoid设置XComponent回调的contextsetDebugopen: booleanvoid设置日志开关native_setup无void初始化配置setDataSourceurl: stringvoid设置视频源地址setDataSourceHeaderheaders: Mapvoid设置视频源的HTTP请求头setOptioncategory:string, key: string, value: stringvoid设置播放前预设参数setOptionLongcategory:string, key: string, value: stringvoid设置播放前预设参数prepareAsync无void加载视频start无void播放视频stop无void停止播放pause无void暂停播放reset无void视频重置release无void释放资源seekTomsec: stringvoid快进、后退setScreenOnWhilePlayingon: booleanvoid设置屏幕常亮setSpeedspeed: stringvoid设置播放倍数getSpeed无number获取设置的倍数isPlaying无boolean查看是否正在播放状态setOnVideoSizeChangedListenerlistener: OnVideoSizeChangedListenervoid设置获取视频宽高回调监听setOnPreparedListenerlistener: OnPreparedListenervoid设置视频准备就绪回调监听setOnInfoListenerlistener: OnInfoListenervoid设置播放器的各种状态回调监听setOnErrorListenerlistener: OnErrorListenervoid设置播放异常回调监听setOnBufferingUpdateListenerlistener: OnBufferingUpdateListenervoid设置buffer缓冲回调监听setOnSeekCompleteListenerlistener: OnSeekCompleteListenervoid设置快进后退回调监听setMessageListener无void设置视频监听器到napi用于接收回调getVideoWidth无number获取视频宽度getVideoHeight无number获取视频高度getVideoSarNum无number获取视频高度getVideoSarDen无number获取视频高度getDuration无number获取视频总的时长getCurrentPosition无number获取视频播放当前位置getAudioSessionId无number获取音频sessionIDsetVolumeleftVolume: string,rightVolume:stringvoid设置音量setLoopCountlooping: booleanvoid设置循环播放isLooping无boolean查看当前是否循环播放selectTracktrack: stringvoid选择轨道deselectTracktrack: stringvoid删除选择轨道getMediaInfo无object获取媒体信息

依赖的三方库编译指导

1、FFmpeg:基于B站的FFmpeg版本(ff4.0–ijk0.8.8–20210426–001):FFmpeg源码链接, 由于工具链问题,请使用GN编译,编译教程参考:OpenHarmony编译构建指导. 编译脚本参考详见目录:doc/FFmpeg/

2、soudtouch:基于B站的soudtouch版本(ijk-r0.1.2-dev):soundtouch源码链接, 标准的库,可直接通过DevEco Studio cmake编译,编译脚本参考详见目录:doc/soundtouch

3、yuv:基于B站的yuv版本(ijk-r0.2.1-dev):yuv源码链接, 标准的库,可直接通过DevEco Studio cmake编译,编译脚本参考详见目录:doc/yuv

约束与限制

在下述版本验证通过:

DevEco Studio版本: 4.1Canary2(4.1.3.322),SDK: API11(4.1.0.36)DevEco Studio版本: 4.1Canary(4.1.3.213),SDK: API11(4.1.2.3)DevEco Studio版本: 4.0(4.0.3.512),SDK: API10(4.0.10.9)DevEco Studio版本: 4.0Canary1(4.0.3.212),SDK: API10(4.0.8.3)

目录结构

|---- ijkplayer

| |---- entry # 示例代码文件夹

| |---- ijkplayer # ijkplayer 库文件夹

| |---- cpp # native模块

| |----- ijkplayer # ijkplayer内部业务

| |----- ijksdl # ijkplayer内部业务

| |----- napi # 封装NAPI接口

| |----- proxy # 代理提供给NAPI调用处理ijkplayer内部业务

| |----- third_party #三方库依赖

| |----- utils #工具

| |---- ets # ets接口模块

| |----- callback #视频回调接口

| |----- common #常量

| |----- utils #工具

| |----- IjkMediaPlayer.ets #ijkplayer暴露的napi调用接口

| |---- README.MD # 安装使用方法

为了能让大家更好的学习鸿蒙(HarmonyOS NEXT)开发技术,这边特意整理了《鸿蒙开发学习手册》(共计890页),希望对大家有所帮助:https://qr21.cn/FV7h05

《鸿蒙开发学习手册》:

如何快速入门:https://qr21.cn/FV7h05

基本概念构建第一个ArkTS应用……

开发基础知识:https://qr21.cn/FV7h05

应用基础知识配置文件应用数据管理应用安全管理应用隐私保护三方应用调用管控机制资源分类与访问学习ArkTS语言……

基于ArkTS 开发:https://qr21.cn/FV7h05

Ability开发UI开发公共事件与通知窗口管理媒体安全网络与链接电话服务数据管理后台任务(Background Task)管理设备管理设备使用信息统计DFX国际化开发折叠屏系列……

鸿蒙开发面试真题(含参考答案):https://qr18.cn/F781PH

鸿蒙开发面试大盘集篇(共计319页):https://qr18.cn/F781PH

1.项目开发必备面试题 2.性能优化方向 3.架构方向 4.鸿蒙开发系统底层方向 5.鸿蒙音视频开发方向 6.鸿蒙车载开发方向 7.鸿蒙南向开发方向

文章来源

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。