Android&HarmonyOS 音视频播放SDK,几句代码即可实现音视频播放功能~
使用简单,功能丰富,支持手机、车机系统、电视、电视盒子、手表等智能设备
常规播放
透明视频
多Surface渲染
多实例播放
播放音频
音量分贝
常规播放
透明视频
多Surface渲染
多实例播放
播放音频
音量分贝
3.1.1 gradle
allprojects {
repositories {
.. .
maven { url ' https://jitpack.io' }
}
}
dependencies {
implementation ' com.github.ywl5320:wlmedia:4.0.1'
}
<uses-permission android : name =" android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android : name =" android.permission.INTERNET" />
defaultConfig {
.. .
ndk {
abiFilter(" armeabi-v7a" )
abiFilter(" arm64-v8a" )
abiFilter(" x86" )
abiFilter(" x86_64" )
}
.. .
}
<-- WlSurfaceView 一般播放使用 -->
<com .ywl5320.wlmedia.widget.WlSurfaceView
android : id =" @+id/wlsurfaceview"
android : layout_width =" match_parent"
android : layout_height =" match_parent" />
<-- WlTextureView 需要做透明、移动、旋转等使用 -->
<com .ywl5320.wlmedia.widget.WlTextureView
android : id =" @+id/wltextureview"
android : layout_width =" match_parent"
android : layout_height =" match_parent" />
// 1.创建播放器
WlPlayer wlPlayer = new WlPlayer ();
wlPlayer .setOnMediaInfoListener (new WlOnMediaInfoListener () {
@ Override
public void onPrepared () {
// 异步准备好后回调,这里调用 wlplayer.start() 开始播放
wlPlayer .start ();
}
@ Override
public void onTimeInfo (double currentTime , double bufferTime ) {
// 时间进度回调
}
@ Override
public void onComplete (WlCompleteType wlCompleteType , String s ) {
// 播放完成回调,根据 WlCompleteType 区分对应类型
if (wlCompleteType == WlCompleteType .WL_COMPLETE_EOF ) {
// 正常播放完成
} else if (wlCompleteType == WlCompleteType .WL_COMPLETE_ERROR ) {
// 播放出错,原因为:msg 字段
} else if (wlCompleteType == WlCompleteType .WL_COMPLETE_HANDLE ) {
// 主动调用 wlPlayer.stop() 会回调此类型
} else if (wlCompleteType == WlCompleteType .WL_COMPLETE_NEXT ) {
// 正在播放中,切换了新的数据源,会回调此类型
} else if (wlCompleteType == WlCompleteType .WL_COMPLETE_TIMEOUT ) {
// 播放超时,会回调此接口
} else if (wlCompleteType == WlCompleteType .WL_COMPLETE_LOOP ) {
// 循环播放中,每开始新的一次循环,会回调此接口
}
}
@ Override
public void onLoad (WlLoadStatus loadStatus , int progress , long speed ) {
// 加载状态回调
if (wlLoadStatus == WlLoadStatus .WL_LOADING_STATUS_START ) {
// 开始加载
} else if (wlLoadStatus == WlLoadStatus .WL_LOADING_STATUS_PROGRESS ) {
// 加载进度
} else if (wlLoadStatus == WlLoadStatus .WL_LOADING_STATUS_FINISH ) {
// 加载完成
}
}
@ Override
public void onSeekFinish () {
// seek 完成回调
}
@ Override
public void onFirstFrameRendered () {
// 首帧渲染回调
}
});
// 2.获取 WlSurfaceView 并绑定播放器
WlSurfaceView wlSurfaceView = findViewById (R .id .wlsurfaceview );
wlSurfaceView .setWlPlayer (wlPlayer );
// 可选
wlSurfaceView .setClearLastVideoFrame (false ); // 设置不清屏
wlSurfaceView .setVideoScale (WlScaleType .WL_SCALE_FIT ); // 设置缩放模式
wlSurfaceView .setVideoRotate (WlRotateType .WL_ROTATE_90 ); // 设置旋转角度
wlSurfaceView .setVideoMirror (WlMirrorType .WL_MIRROR_TOP_BOTTOM ); // 设置镜像模式
// 3.设置数据源异步准备
wlPlayer .setSource (url );
wlPlayer .prepare ();
ohpm i @ywl5320/libwlmedia
#module. json5
"requestPermissions" : [
{
"name" : "ohos.permission.INTERNET"
}
]
3.2.3 设置XComponentController
let wlPlayer : WlPlayer = new WlPlayer ( ) ;
let wlComponentController : WlComponentController = new WlComponentController ( this . wlPlayer ) ;
...
XComponent ( {
type : XComponentType . SURFACE ,
controller : this . wlComponentController
} )
. width ( '100%' )
. height ( '100%' )
. . .
@Entry
@Component
struct Index {
private wlPlayer : WlPlayer | null = null ;
private wlComponentController: WlComponentController | null = null ;
aboutToAppear ( ) : void {
this . wlPlayer = new WlPlayer ( ) ;
this . wlPlayer . setOnMediaInfoListener ( {
onPrepared : ( ) : void => {
// 异步准备好后回调,这里调用 wlplayer.start() 开始播放
this . wlPlayer ?. start ( ) ;
} ,
onTimeInfo : ( currentTime : number , bufferTime : number ) : void => {
// 时间进度回调
} ,
onComplete : ( wlCompleteType : WlCompleteType , msg : string ) : void => {
if ( wlCompleteType == WlCompleteType . WL_COMPLETE_EOF ) {
// 正常播放完成
} else if ( wlCompleteType == WlCompleteType . WL_COMPLETE_ERROR ) {
// 播放出错,原因为:msg 字段
} else if ( wlCompleteType == WlCompleteType . WL_COMPLETE_HANDLE ) {
// 主动调用 wlPlayer.stop() 会回调此类型
} else if ( wlCompleteType == WlCompleteType . WL_COMPLETE_NEXT ) {
// 正在播放中,切换了新的数据源,会回调此类型
} else if ( wlCompleteType == WlCompleteType . WL_COMPLETE_TIMEOUT ) {
// 播放超时,会回调此接口
} else if ( wlCompleteType == WlCompleteType . WL_COMPLETE_LOOP ) {
// 循环播放中,每开始新的一次循环,会回调此接口
}
} ,
onLoadInfo : ( loadStatus : WlLoadStatus , progress : number , speed : number ) : void => {
// 加载状态回调
if ( wlLoadStatus == WlLoadStatus . WL_LOADING_STATUS_START ) {
// 开始加载
} else if ( wlLoadStatus == WlLoadStatus . WL_LOADING_STATUS_PROGRESS ) {
// 加载进度
} else if ( wlLoadStatus == WlLoadStatus . WL_LOADING_STATUS_FINISH ) {
// 加载完成
}
} ,
onFirstFrameRendered : ( ) : void => {
// seek 完成回调
} ,
onSeekFinish : ( ) : void => {
// seek 完成回调
} ,
onAudioInterrupt : ( type : WlAudioInterruptType , hint : WlAudioInterruptHint ) => {
// 音频打断,和系统一致
}
this . wlComponentController = new WlComponentController ( this . wlPlayer ) ;
this . wlPlayer . setClearLastVideoFrame ( this . wlComponentController . getUniqueNum ( ) , false ) ;
}
// 退出 销毁资源
onBackPress ( ) : boolean | void {
this . wlPlayer ?. release ( )
}
build ( ) {
Column ( ) {
XComponent ( {
type : XComponentType . SURFACE ,
controller : this . wlComponentController
} )
. onLoad ( ( event ) => {
// 加载完成后就开始播放
this . wlPlayer ?. setSource ( this . filesDir + "/huoying_cut.mkv" ) ;
this . wlPlayer ?. prepare ( ) ;
} )
. width ( '100%' )
. height ( '100%' )
}
}
}
WlMedia
是按应用根据 包名
定制的,分免费版和付费定制版
如要定制去水印,可付费根据包名定制打包,具体费用和规则请邮件联系:
Update By:ywl5320 2025-02-04
Create By:ywl5320 2019-12-16