Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Android 音视频播放SDK,几句代码即可实现音视频播放功能(支持:手机、电视盒子等设备。支持:http、https、rtsp、rtp、rtmp、byte[]、加密视频和各种文件格式视频;包含视频截图、音轨选择、设置软解或硬解、自定义视频滤镜、变速变调、声道切换、无缝切换surface(surfaceview和textureview)、视频比例设置、多路音视频播放等。)~

License

Notifications You must be signed in to change notification settings

luojianping168/wlmedia

Folders and files

NameName
Last commit message
Last commit date

Latest commit

History

32 Commits

Repository files navigation

wlmedia

Android 音视频播放SDK,几句代码即可实现音视频播放功能~
支持手机、电视盒子等设备。

注意 重点重点重点

如果你使用了本库,请务必告知我一下,不然我更新版本可能会删除某些历史库,可能会给你带来不必要的麻烦,请悉知!!!

功能

**支持:http、https、rtsp、rtp、rtmp、byte[]、加密视频、多路音视频播放和各种文件格式视频;
**截图、音轨切换、自定义视频滤镜、变速变调、声道切换、无缝切换surface(surfaceview和textureview)、视频比例自定义设置等;
**目前包含全部FFmpeg音视频解码器,故SDK包比较大;如需定制大小,可联系我~(Email:ywl5320@163.com)

连续播放10小时直播内存情况


电视盒子播放

电视直播

多路视频播放

多屏视频切换

1、Usage(可用手机(我是移动)分享热点的方式加速下载)

Gradle: Download

implementation 'ywl.ywl5320:wlmedia:1.0.7'

2、实例图片



3、调用方式

配置NDK编译平台:

defaultConfig {
 ...
	ndk {
	 abiFilter("arm64-v8a")
	 abiFilter("armeabi-v7a")
	 abiFilter("x86")
	 abiFilter("x86_64")
	}
	...
}

基本权限

<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INTERNET"/>

4、接入代码

4.1、视频surface选择

	// WlSurfaceView 一般播放使用
	<com.ywl5320.wlmedia.surface.WlSurfaceView
 android:layout_width="match_parent"
 android:layout_height="match_parent" />

	// WlTextureView 需要做透明、移动、旋转等使用
 <com.ywl5320.wlmedia.surface.WlTextureView
 android:layout_width="match_parent"
 android:layout_height="match_parent" />

4.2、创建播放器

4.2.1 播放视频
	WlMedia wlMedia = new WlMedia();//创建一个播放实例
 wlMedia.setPlayModel(WlPlayModel.PLAYMODEL_AUDIO_VIDEO);//同时播放音频视频
	wlSurfaceView.setWlMedia(wlMedia);//给视频surface设置播放器
	
	//异步准备完成后开始播放
	wlMedia.setOnPreparedListener(new WlOnPreparedListener() {
 @Override
 public void onPrepared() {
 wlMedia.start();//开始播放
 }
 });
 //surface初始化好了后 开始播放视频(用于一打开activity就播放场景)
 wlSurfaceView.setOnVideoViewListener(new WlOnVideoViewListener() {
 @Override
 public void initSuccess() {
 wlMedia.setSource("/storage/sdcard1/fcrs.1080p.mp4");//设置数据源
 wlMedia.prepared();//异步开始准备播放
 }
 @Override
 public void moveSlide(double value) {
 }
 @Override
 public void movdFinish(double value) {
 wlMedia.seek(value);//seek
 }
 });
 //自定义滤镜方式
 String fs = "precision mediump float;" +
 "varying vec2 ft_Position;" +
 "uniform sampler2D sTexture; " +
 "void main() " +
 "{ " +
 "vec4 v=texture2D(sTexture, ft_Position); " +
 "float average = (v.r + v.g + v.b) / 3.0;" +
 "gl_FragColor = vec4(average, average, average, v.a);" +
 "}";
 wlMedia.setfShader(fs);
 wlMedia.changeFilter();
4.2.2 播放音频
 WlMedia wlMedia = new WlMedia();
 wlMedia.setPlayModel(WlPlayModel.PLAYMODEL_ONLY_AUDIO);//设置只播放音频(必须)
 wlMedia.setSource(WlAssetsUtil.getAssetsFilePath(this, "mydream.m4a"));//设置数据源
 wlMedia.setOnPreparedListener(new WlOnPreparedListener() {
 @Override
 public void onPrepared() {
 wlMedia.start();
 }
 });
 wlMedia.prepared();
4.2.3 播放加密视频文件
 WlMedia wlMedia = new WlMedia();
 wlMedia.setPlayModel(WlPlayModel.PLAYMODEL_AUDIO_VIDEO);
 wlSurfaceView.setWlMedia(wlMedia);
 wlMedia.setBufferSource(true, true);//必须都为true
 wlMedia.setOnDecryptListener(new WlOnDecryptListener() {
 
 //解密算法
 @Override
 public byte[] decrypt(byte[] encrypt_data) {
 int length = encrypt_data.length;
 for(int i = 0; i < length; i++)
 {
 encrypt_data[i] = (byte) ((int)encrypt_data[i] ^ 666);
 }
 WlLog.d("decrypt");
 return encrypt_data;
 }
 });
 wlSurfaceView.setOnVideoViewListener(new WlOnVideoViewListener() {
 @Override
 public void initSuccess() {
 wlMedia.setSource(WlAssetsUtil.getAssetsFilePath(WlEncryptActivity.this, "fhcq-ylgzy-dj-encrypt.mkv"));//加密视频源
 wlMedia.prepared();
 }
 @Override
 public void moveSlide(double value) {
 }
 @Override
 public void movdFinish(double value) {
 wlMedia.seek(value);
 }
 });
4.2.4 播放byte[]音视频数据
 wlMedia = new WlMedia();
 wlMedia.setBufferSource(true, false);//必须第一个为true,第二个为false
 wlMedia.setPlayModel(WlPlayModel.PLAYMODEL_ONLY_VIDEO);//根据byte类型来设置(可以音频、视频、音视频)
 wlTextureView.setWlMedia(wlMedia);
 wlMedia.setOnPreparedListener(new WlOnPreparedListener() {
 @Override
 public void onPrepared() {
 wlMedia.start();
 }
 });
 wlTextureView.setOnVideoViewListener(new WlOnVideoViewListener() {
 @Override
 public void initSuccess() {
 new Thread(new Runnable() {
 long length = 0;
 @Override
 public void run() {
 try {
 //从文件模拟byte[]数据
 File file = new File(WlAssetsUtil.getAssetsFilePath(WlBufferActivity.this, "mytest.h264"));
 FileInputStream fi = new FileInputStream(file);
 byte[] buffer = new byte[1024 * 64];
 int buffersize = 0;
 int bufferQueueSize = 0;
 exit = false;
 while(true)
 {
 if(exit)
 {
 break;
 }
 if(wlMedia.isPlay())
 {
 WlLog.d("read thread " + bufferQueueSize);
 if(bufferQueueSize < 20)//控制队列大小,不然内存可能会增大溢出
 {
 buffersize = fi.read(buffer);
 if(buffersize <= 0)
 {
 WlLog.d("read thread ============================== read buffer exit ...");
 wlMedia.putBufferSource(null, -1);
 break;
 }
 bufferQueueSize = wlMedia.putBufferSource(buffer, buffersize);//返回值为底层buffer队列个数
 while(bufferQueueSize < 0)
 {
 bufferQueueSize = wlMedia.putBufferSource(buffer, buffersize);
 }
 }
 else
 {
 bufferQueueSize = wlMedia.putBufferSource(null, 0);
 }
 sleep(10);
 }
 else
 {
 WlLog.d("buffer exit");
 break;
 }
 }
 wlMedia.stop();
 } catch (Exception e) {
 e.printStackTrace();
 }
 }
 }).start();
 wlMedia.prepared();
 }
 @Override
 public void moveSlide(double value) {
 }
 @Override
 public void movdFinish(double value) {
 }
 });
4.2.5 获取视频图片(类似于缩略图)
	WlMediaUtil wlMediaUtil = new WlMediaUtil();//可以用单利模式,自己封装图片加载库
	Bitmap bitmap = wlMediaUtil.getVideoPic(url);

5、API

5.1 播放器API

 public WlMedia();//构造函数,不依赖上下文
 
 public void setSource(String source);//设置数据源(可以是file、url)
 
 public void setPlayModel(WlPlayModel playModel);//设置音视频播放模式(可以独立播放音频和视频或者同时播放音视频,默认同时播放音视频)
 
 public void setCodecType(WlCodecType codecType);//设置解码器类型(默认优先使用硬解码)
 
 public void prepared();异步开始准备播放,成功后会回调WlOnPreparedListener接口
 
 public void next();//切歌(数据源设置方法为:setSource)
 
 public void start();//开始播放(当异步准备完成后,在WlOnPreparedListener回调里面开始播放)
 
 public void pause();//播放暂停
 
 public void resume();//暂停后恢复播放
 
 public boolean isPlay();//判断是否在播放中
 
 public void setMute(WlMute mute);//设置声道(立体声、左声道、右声道)
 
 public void setVolume(int percent);//设置声音(0~100)
 
 public void setSpeed(float speed);//设置播放速度(0.5f~2f)
 
 public void setPitch(float pitch);//设置播放音调(0.5f~2f)
 
 public void seek(double secds);//seek 目前是到关键帧(实测精确到时间帧,体验不好,平均等待时间过长,故弃之)
 
 public void setSampleRate(WlSampleRate wlSampleRate);//设置音频采样率(用于回调pcm时需要制定采样率情况)
 
 public void setShowPcm(boolean showPcm);//设置是否回调pcm音频数据,回调方法:WlOnPcmDataListener
 
 public double getNowClock();//获取当前播放时间
 
 public double getDuration();//获取时长(如果有在异步准备好后可获取)
 
 public void takePicture();//视频截图(是截取surface屏幕图片,自己可根据surface大小和视频宽高对视频图片进行裁剪),回调方法:WlOnTakePictureListener
 
 public int putBufferSource(byte[] buffer, int buffer_len);//byte[]方式播放数据入口,返回值为底层队列大小,当buffer_len == 0时,也返回底层队列大小。
 
 public void seekNoCallTime();//设置不回调时间,可用于seek过程中UI展示(具体看自己的需求)
 
 public void onSurfaceCreate(Surface surface);//设置surface(用于自定义surfaceview)
 
 public void onSurfaceChange(int width, int height, Surface surface);//surface大小改变
 
 public void onSurfaceDestroy();//surface销毁
 
 public void release();//回收surface底层opengl资源
 
 public void setTransportModel(WlTransportModel transportModel);//设置播放rtsp的方式(UDP/TCP)
 
 public void setClearLastPicture(boolean clearLastPicture);//视频播放完最后一帧是否清屏,true:停留在最后一帧;false:清屏为黑色
 
 /**
 * 设置数据源模式
 * 1、bufferSource为true,encryptFileSource为false时,是byte[]模式
 * 2、bufferSource为true,encryptFileSource为true时,是file模式,可用于加密视频播放,(回WlOnDecryptListener调里面自己解密)
 * @param bufferSource byte[]模式
 * @param encryptFileSource 是否加密
 */
 public void setBufferSource(boolean bufferSource, boolean encryptFileSource);
 
 public void setvShader(String vShader);//设置顶点着色器
 
 public void setfShader(String fShader);//设置纹理着色器
 
 public void changeFilter();//设置着色器后用于使之生效(切换滤镜)
 
 public void scaleVideo(int w, int h);//设置视频宽高比
 
 public int getVideoWidth();//获取视频宽
 
 public int getVideoHeight();//获取视频高
 
 public String[] getAudioChannels();//获取所有音轨,返回音轨名字(默认为Audio)
 
 public void setAudioChannel(int index);//设置播放音轨,index为getAudioChannels中得到音轨的索引
	
	public void setDelayOffsetTime(double offsetTime);//用于单独播放视频(buffer)时动态调整视频渲染速率,单位秒。

5.2 WlSurfaceView和WlTextureView

SDK自带这2个自定义surfaceview,通过setWlMedia方法与播放器关联,updateMedia方法用于播放中切换显示surface;WlOnVideoViewListener为surface初始化完成回调。
开发者可以根据自己情况自定义自己的surfaceview,实现自己的特殊需求。
***注:***
自定义surface必须调用方法:
 public void onSurfaceCreate(Surface surface);
 
 public void onSurfaceChange(int width, int height, Surface surface);
 
 public void onSurfaceDestroy();

5.3 回调函数

 public interface WlOnPreparedListener; //异步准备完成回调
 
 public interface WlOnTimeInfoListener; //播放时间回调
 
 public interface WlOnLoadListener; //加载状态回调
 
 public interface WlOnErrorListener; //错误回调
 
 public interface WlOnCompleteListener; //播放(资源回收)完成回调
 
 public interface WlOnDecryptListener; //解密算法回调
 
 public interface WlOnPcmDataListener; //音频PCM数据回调
 
 public interface WlOnTakePictureListener; //截图回调
 
 public interface WlOnVideoViewListener; //surface 初始化完成回调

6、混淆

-keep class com.ywl5320.wlmedia.* {*;} 

7、注意事项

7.1 播放器activity配置:

android:configChanges="orientation|keyboardHidden|screenSize"

7.2 播放器生命周期逻辑

7.2.1、对于视频播放,new一个对象就对应播放一路视频,在退出播放页面时,调用release才能销毁surfaceview资源(音频则不需要)。
7.2.2、对于音频,new一个对象就对应播放一个音频,PlayModel设置为:WlPlayModel.PLAYMODEL_ONLY_AUDIO 即可。
7.3.3、常规播放流程(具体可看demo):
如:APP启动->startactivity->new WlMedia()->播放中各种操作->关闭播放页面(stop->complete/orerror->activityfinish(release))

7.3 高本版系统后台播放音频卡顿问题

建议在新的进程中播放音频,比如:
<service android:name=".AudioService"
 android:process=":wlmedia"/>
 
 绑定服务
bindService(intent,serviceConnection,BIND_WAIVE_PRIORITY);//注意第三个参数BIND_WAIVE_PRIORITY

8、使用本库APP(如果你的APP使用了本库,也可以告诉我哦~)

荟声 睿芯智能 ......

9、参考资料

10、核心三方库

FFmpeg OpenSSL SoundTouch

Create By:ywl5320 2019年12月16日

About

Android 音视频播放SDK,几句代码即可实现音视频播放功能(支持:手机、电视盒子等设备。支持:http、https、rtsp、rtp、rtmp、byte[]、加密视频和各种文件格式视频;包含视频截图、音轨选择、设置软解或硬解、自定义视频滤镜、变速变调、声道切换、无缝切换surface(surfaceview和textureview)、视频比例设置、多路音视频播放等。)~

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Java 100.0%

AltStyle によって変換されたページ (->オリジナル) /