【VLC-Android】vlc-android简例
前言
继续折腾vlc,做这个例子并不顺利,卡在只有声音没有图像这个问题好久,网上的例子有些API已经对不上,继续分享,,,
声明
欢迎转载,但请保留文章原始出处:)
博客园:http://www.cnblogs.com
农民伯伯: http://over140.cnblogs.com
正文
截图
项目
代码
public class VlcVideoActivity extends Activity implements SurfaceHolder.Callback, IVideoPlayer {
private final static String TAG = "[VlcVideoActivity]";
private SurfaceView mSurfaceView;
private LibVLC mMediaPlayer;
private SurfaceHolder mSurfaceHolder;
private View mLoadingView;
private int mVideoHeight;
private int mVideoWidth;
private int mVideoVisibleHeight;
private int mVideoVisibleWidth;
private int mSarNum;
private int mSarDen;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_video_vlc);
mSurfaceView = (SurfaceView) findViewById(R.id.video);
mLoadingView = findViewById(R.id.video_loading);
try {
mMediaPlayer = VLCInstance.getLibVlcInstance();
} catch (LibVlcException e) {
e.printStackTrace();
}
mSurfaceHolder = mSurfaceView.getHolder();
mSurfaceHolder.setFormat(PixelFormat.RGBX_8888);
mSurfaceHolder.addCallback(this);
mMediaPlayer.eventVideoPlayerActivityCreated(true);
EventHandler em = EventHandler.getInstance();
em.addHandler(mVlcHandler);
this.setVolumeControlStream(AudioManager.STREAM_MUSIC);
mSurfaceView.setKeepScreenOn(true);
// mMediaPlayer.setMediaList();
// mMediaPlayer.getMediaList().add(new Media(mMediaPlayer, "http://live.3gv.ifeng.com/zixun.m3u8"), false);
// mMediaPlayer.playIndex(0);
mMediaPlayer.playMRL("http://live.3gv.ifeng.com/zixun.m3u8");
}
@Override
public void onPause() {
super.onPause();
if (mMediaPlayer != null) {
mMediaPlayer.stop();
mSurfaceView.setKeepScreenOn(false);
}
}
@Override
protected void onDestroy() {
super.onDestroy();
if (mMediaPlayer != null) {
mMediaPlayer.eventVideoPlayerActivityCreated(false);
EventHandler em = EventHandler.getInstance();
em.removeHandler(mVlcHandler);
}
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
setSurfaceSize(mVideoWidth, mVideoHeight, mVideoVisibleWidth, mVideoVisibleHeight, mSarNum, mSarDen);
super.onConfigurationChanged(newConfig);
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
if (mMediaPlayer != null) {
mSurfaceHolder = holder;
mMediaPlayer.attachSurface(holder.getSurface(), this);
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
mSurfaceHolder = holder;
if (mMediaPlayer != null) {
mMediaPlayer.attachSurface(holder.getSurface(), this);//, width, height
}
if (width > 0) {
mVideoHeight = height;
mVideoWidth = width;
}
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
if (mMediaPlayer != null) {
mMediaPlayer.detachSurface();
}
}
@Override
public void setSurfaceSize(int width, int height, int visible_width, int visible_height, int sar_num, int sar_den) {
mVideoHeight = height;
mVideoWidth = width;
mVideoVisibleHeight = visible_height;
mVideoVisibleWidth = visible_width;
mSarNum = sar_num;
mSarDen = sar_den;
mHandler.removeMessages(HANDLER_SURFACE_SIZE);
mHandler.sendEmptyMessage(HANDLER_SURFACE_SIZE);
}
private static final int HANDLER_BUFFER_START = 1;
private static final int HANDLER_BUFFER_END = 2;
private static final int HANDLER_SURFACE_SIZE = 3;
private static final int SURFACE_BEST_FIT = 0;
private static final int SURFACE_FIT_HORIZONTAL = 1;
private static final int SURFACE_FIT_VERTICAL = 2;
private static final int SURFACE_FILL = 3;
private static final int SURFACE_16_9 = 4;
private static final int SURFACE_4_3 = 5;
private static final int SURFACE_ORIGINAL = 6;
private int mCurrentSize = SURFACE_BEST_FIT;
private Handler mVlcHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
if (msg == null || msg.getData() == null)
return;
switch (msg.getData().getInt("event")) {
case EventHandler.MediaPlayerTimeChanged:
break;
case EventHandler.MediaPlayerPositionChanged:
break;
case EventHandler.MediaPlayerPlaying:
mHandler.removeMessages(HANDLER_BUFFER_END);
mHandler.sendEmptyMessage(HANDLER_BUFFER_END);
break;
case EventHandler.MediaPlayerBuffering:
break;
case EventHandler.MediaPlayerLengthChanged:
break;
case EventHandler.MediaPlayerEndReached:
//播放完成
break;
}
}
};
private Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case HANDLER_BUFFER_START:
showLoading();
break;
case HANDLER_BUFFER_END:
hideLoading();
break;
case HANDLER_SURFACE_SIZE:
changeSurfaceSize();
break;
}
}
};
private void showLoading() {
mLoadingView.setVisibility(View.VISIBLE);
}
private void hideLoading() {
mLoadingView.setVisibility(View.GONE);
}
private void changeSurfaceSize() {
// get screen size
int dw = getWindowManager().getDefaultDisplay().getWidth();
int dh = getWindowManager().getDefaultDisplay().getHeight();
// calculate aspect ratio
double ar = (double) mVideoWidth / (double) mVideoHeight;
// calculate display aspect ratio
double dar = (double) dw / (double) dh;
switch (mCurrentSize) {
case SURFACE_BEST_FIT:
if (dar < ar)
dh = (int) (dw / ar);
else
dw = (int) (dh * ar);
break;
case SURFACE_FIT_HORIZONTAL:
dh = (int) (dw / ar);
break;
case SURFACE_FIT_VERTICAL:
dw = (int) (dh * ar);
break;
case SURFACE_FILL:
break;
case SURFACE_16_9:
ar = 16.0 / 9.0;
if (dar < ar)
dh = (int) (dw / ar);
else
dw = (int) (dh * ar);
break;
case SURFACE_4_3:
ar = 4.0 / 3.0;
if (dar < ar)
dh = (int) (dw / ar);
else
dw = (int) (dh * ar);
break;
case SURFACE_ORIGINAL:
dh = mVideoHeight;
dw = mVideoWidth;
break;
}
mSurfaceHolder.setFixedSize(mVideoWidth, mVideoHeight);
ViewGroup.LayoutParams lp = mSurfaceView.getLayoutParams();
lp.width = dw;
lp.height = dh;
mSurfaceView.setLayoutParams(lp);
mSurfaceView.invalidate();
}
}
代码说明
1、vlc-android的版本为2.2.0-pre1 Weatherwax
2、拷贝vlc-android官网例子下面org.videolan.libvlc所有的类,以及VLCInstance、 Preferences。只有声音没有画面就出在VLCInstance这个问题上,少了一些配置,参考 VLCInstance.updateLibVlcSettings。
3、playMRL不要用Uri来转,否则打不开
4、提供的代码已经编译好了so,也修改源码打开了EventHandler.MediaPlayerBuffering(也修改了libvlcjni.c),但是还是没有缓冲进度的值,还有待进一步探索。
5、实际发现如果只在surfaceChanged中attachSurface,setSurfaceSize回调不会触发,需要同时在surfaceCreated中设置。
6、本文不讨论Handler非静态可能引发内存泄露的问题,大家写的时候自己注意一下 :)
下载
https://github.com/over140/vlc-android-demo (注意工程是Android Studio的工程)
文章
1、vlc-android 中调用用libvlcjni.so实现流媒体播放
2、[Github]vlc-android-macbuild
5、vlc-android 获取MediaPlayerEncounteredError,MediaPlayerBuffering等各种事件的响应
结束
文章2的GitHub项目是对vlc进行封装,也挺不错了,值得参考。vlc-android的例子写的比较复杂,而且api可能老变,大家看文章的时候注意一下版本问题。
相关文章
- 安卓逆向_15( 二 ) --- Android Studio 3.6.3 JNI 环境配置 和 so 生成开发 demo
- Android系统自带的android.util.Base64的实现源码
- Android-黑科技-微信抢红包必备软件
- Android 开源项目android-open-project解析之(二) GridView,ImageView,ProgressBar,TextView
- Android SwipeToDismiss:左滑/右滑删除ListView条目Item
- Android:图片中叠加文字,支持拖动改变位置
- Android 异常 android.os.NetworkOnMainThreadException
- Android 8.1 MTK root版本解决方案
- Android 判断手机是32位CPU还是64位CPU android.os.Build类字段含义
- Android编程心得-使用ActionBar+Fragment+ViewPager实现动态切换Menu效果
- Android之 ImageView android:src和tools:src的区别是什么?
- Android菜单详解(一)——理解android中的Menu
- Android-如何显示版本号并制作3秒跳转页
- 【APP渗透测试】Android APK常用测试工具(Drozer)安装及使用方法介绍
- android常见错误-The container 'Android Dependencies' references non existing library
- Android-Unable to resolve target 'android-8'
- 《Android安全技术揭秘与防范》—第8章8.2节常用的Hook工具
- 《Android游戏开发详解》一2.3 编写第一个程序
- Android bitmap序列化
- android编译系统的makefile文件Android.mk写法如下
- 【VLC-Android】LibVLC API简介(相当于VLC的MediaPlayer)
- 【VLC-Android】Mac下编译vlc-android
- android:descendantFocusability用法简析
- android开发:Android 中自定义属性(attr.xml,TypedArray)的使用
- android studio 完整安装教程,已完全实践过
- Android Framework 面试集合——Binder篇
- android平板对接扫码枪,切换输入设备弹出键盘问题
- 解决Android SDK Manager下载问题和android studio每次启动都要在fetching Android sdk compoment information
- 在 Android Studio 2.2 中愉快地使用 C/C++
- Eclipse中Android单元测试
- 【Android开发经验】android:windowSoftInputMode属性具体解释
- Android bluetooth介绍(两): android 蓝牙源架构和uart 至rfcomm过程
- android_我的第一个Android程序
- Android Studio中使用AAR包