【VLC-Android】vlc-android简例

 

前言

  继续折腾vlc,做这个例子并不顺利,卡在只有声音没有图像这个问题好久,网上的例子有些API已经对不上,继续分享,,,

 

声明
  欢迎转载,但请保留文章原始出处:)
    博客园:http://www.cnblogs.com
    农民伯伯: http://over140.cnblogs.com

 

正文

  截图

    【VLC-Android】vlc-android简例

  项目

    【VLC-Android】vlc-android简例

  代码

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

    3、vlc android的编译及截图,录制视频等功能

    4、vlc-android源码编译过程记录

    5、vlc-android 获取MediaPlayerEncounteredError,MediaPlayerBuffering等各种事件的响应

    6、Vlc-for-android源码分析

 

结束

   文章2的GitHub项目是对vlc进行封装,也挺不错了,值得参考。vlc-android的例子写的比较复杂,而且api可能老变,大家看文章的时候注意一下版本问题。

你可能感兴趣的:(android)