android多媒体(播放视频)

Android多媒体的编写主要是播放器的选择,总的来说有两种选择。
1.选用android原生videoview控件,这是最简单的办法,但是videoview的功能有限,涉及到一些操作是无法实现的。
videoview实现很简单。代码如下。
布局文件中声明控件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_gravity="center"
    tools:context=".MainActivity">

 <VideoView
     android:id="@+id/videoview"
     android:layout_width="match_parent"
     android:layout_height="match_parent"/>

</LinearLayout>

activity中使用:

private VideoView videoView;
videoView = (VideoView)findViewById(R.id.videoview);
videoView.setVideoPath("http://live.hkstv.hk.lxdns.com/live/hks/playlist.m3u8");  // 香港卫视地址
videoView.start();
//使视频能够暂停、播放、进度条显示等控制
MediaController mediaController = new MediaController(this);
videoView.setMediaController(mediaController);
mediaController.setMediaPlayer(videoView);

manifest中声明权限


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

如果是本地视频路径setVideoPath()括号中换成本地视频路径即可。
也可以使用自定义VIdeoview控件实现播放视频,这样有更多的可操作性
2.选用Meidaplayer + surfaceView播放视频。
将mediaplayer的方法集成到一个类中

public class SambaVideoPlayer extends FrameLayout {

    private String TAG = "SambaVideoPlayer";

    private Context mContext;
    private IMediaPlayer mMediaPlayer;
    private SurfaceView surfaceView;
    private static int currentPosition;
    private static int duration;

    public static boolean isPreparing = false;

    public SambaVideoPlayer(Context context) {
        super(context);
    }

    public SambaVideoPlayer(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    private void init(Context context) {
        mContext = context;
        createSurfaceView();
    }

    private void createSurfaceView() {
        surfaceView = new SurfaceView(mContext);
        surfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {
            @Override
            public void surfaceCreated(SurfaceHolder holder) {

            }

            @Override
            public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
                if (mMediaPlayer != null) {
                    mMediaPlayer.setDisplay(holder);
                }
            }

            @Override
            public void surfaceDestroyed(SurfaceHolder holder) {

            }
        });
        LayoutParams layoutParams =
                new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT,
                        Gravity.CENTER);
        addView(surfaceView, 0, layoutParams);
    }

    //创建一个新的player
    private IMediaPlayer createPlayer() {
        //todo 各个参数的含义
        IjkMediaPlayer ijkMediaPlayer = new IjkMediaPlayer();
        ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "opensles", 1);

        ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "overlay-format", IjkMediaPlayer.SDL_FCC_RV32);
        ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "framedrop", 1);
        ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "start-on-prepared", 0);

        ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "http-detect-range-support", 1);

        ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_CODEC, "skip_loop_filter", 48);
        ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_CODEC, "min-frames", 100);
        ijkMediaPlayer.setOption(IjkMediaPlayer.OPT_CATEGORY_PLAYER, "enable-accurate-seek", 1);

        ijkMediaPlayer.setVolume(1.0f, 1.0f);

        return ijkMediaPlayer;
    }

    //开始加载视频
    public void load(String mPath) throws IOException {
        if (mMediaPlayer != null) {
            mMediaPlayer.stop();
            mMediaPlayer.release();
        }
        mMediaPlayer = createPlayer();

        mMediaPlayer.setDisplay(surfaceView.getHolder());
        mMediaPlayer.setDataSource(mContext, Uri.parse(mPath));
        mMediaPlayer.prepareAsync();
        // setListener(mMediaPlayer);

        Log.d(TAG, "prepareAsync");
    }

    private void setListener(IMediaPlayer player) {
        Log.d(TAG, "setListener");
        player.setOnPreparedListener(new IMediaPlayer.OnPreparedListener() {
            @Override
            public void onPrepared(IMediaPlayer iMediaPlayer) {
                Log.d(TAG, "onPrepared");
                if (mMediaPlayer != null) {
                    mMediaPlayer.start();
                    Log.d(TAG, "mMediaPlayer.start();" + mMediaPlayer.getDuration());
                }
                isPreparing = true;
            }
        });
        player.setOnVideoSizeChangedListener(new IMediaPlayer.OnVideoSizeChangedListener() {
            @Override
            public void onVideoSizeChanged(IMediaPlayer iMediaPlayer, int i, int i1, int i2, int i3) {

            }
        });
    }

    public void setOnPreparedListener(IMediaPlayer.OnPreparedListener preparedListener) {
        mMediaPlayer.setOnPreparedListener(preparedListener);
    }


    public boolean isSmabaPlaying() {
        if (mMediaPlayer != null) {
            return mMediaPlayer.isPlaying();
        }
        return false;
    }


    public void play() {
        if (mMediaPlayer != null) {
            mMediaPlayer.start();
        }
    }

    public void release() {
        if (mMediaPlayer != null) {
            mMediaPlayer.reset();
            mMediaPlayer.release();
            mMediaPlayer = null;
        }
    }

    public void pause() {
        if (mMediaPlayer != null) {
            mMediaPlayer.pause();
        }
    }

    public void stop() {
        if (mMediaPlayer != null) {
            mMediaPlayer.stop();
        }
    }

    public void reset() {
        if (mMediaPlayer != null) {
            mMediaPlayer.reset();
        }
    }
    public void seekTo(long position) {
        if (mMediaPlayer != null){
            mMediaPlayer.seekTo(position);
        }
    }

    public ITrackInfo[] getTrackInfo() {
        String mime = "und";
        if(mMediaPlayer != null){
            ITrackInfo[] iTracks = mMediaPlayer.getTrackInfo();
            MediaInfo mediaInfo = mMediaPlayer.getMediaInfo();
            Log.d(TAG, "iTracks" + mediaInfo.mVideoDecoder);
            for(ITrackInfo info : iTracks){
                Log.d(TAG, "iTracks" + info.getFormat());
                if(info.getTrackType() == MediaPlayer.TrackInfo.MEDIA_TRACK_TYPE_VIDEO){
//                    MediaFormat mediaFormat = (MediaFormat)info.getFormat();
                    Log.d(TAG,"getVideoMimeType ~ mime==" + info.getFormat());
//                    if (mediaFormat != null){
//                        mime = mediaFormat.getString(MediaFormat.KEY_MIME);
//                        Log.d(TAG,"getVideoMimeType ~ mime==" + mime);
//                        break;
//                    }
                }
            }
            return iTracks;
        }
        return null;
    }

}

播放活动中调用

public class SambaPlayActivity extends Activity {

    private String TAG = "SambaPlayActivity";

    private static final int PROGRESS_CHANGE = 0;

    private View contentView;

    private RelativeLayout parentLayout;

    private ControlView mControlView;

    protected int mDisPlayWidth;

    protected int mDisPlayHeight;

    private int position;

    boolean isplaying;

    SambaVideoPlayer sambaVideoPlayer;

    final Handler myHandler = new Handler() {
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case PROGRESS_CHANGE:
                    mControlView.setCurrentTime(position);
                    mControlView.setProgress(position);
                    //Log.d(TAG, "PROGRESS_CHANGE" + position);
                    break;
            }
        }
    };

    public static SambaPlayActivity mInstance;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.samba_video_layout);

        Const.isSambaPlayer = true;

        sambaVideoPlayer = findViewById(R.id.video);
        parentLayout = findViewById(R.id.samba_layout);

        mInstance = this;

        Uri uri = getIntent().getData();
        Log.d(TAG, "uri" + uri);
        try {
            sambaVideoPlayer.load(uri.toString());
            sambaVideoPlayer.setOnPreparedListener(preparedListener);
        } catch (IOException e) {
            Toast.makeText(this,"播放失败",Toast.LENGTH_SHORT);
            e.printStackTrace();
        }

        DisplayMetrics dm = new DisplayMetrics();
        this.getWindowManager().getDefaultDisplay().getMetrics(dm);
        ScreenConstant.SCREEN_WIDTH = dm.widthPixels;
        ScreenConstant.SCREEN_HEIGHT = dm.heightPixels;

        getPopView(R.layout.mmp_popupvideo, MultiMediaConstant.VIDEO,
                mControlImp);
        showPopUpWindow(parentLayout);

        mControlView.setTimeViewVisibility(true);

        getTrackInfo();

    }

    @Override
    protected void onResume() {
        super.onResume();
    }

    @Override
    protected void onDestroy() {
        isplaying = false;
        Const.isSambaPlayer = false;
        sambaVideoPlayer.stop();
        removeControlView();
        sambaVideoPlayer.release();
        super.onDestroy();
    }

    public static SambaPlayActivity getInstance(){
        return mInstance;
    }


    protected void getPopView(int resource, int mediatype, ControlView.ControlPlayState controlImp) {
        contentView = LayoutInflater.from(SambaPlayActivity.this).inflate(
                resource, null);
        mDisPlayWidth = ScreenConstant.SCREEN_WIDTH;
        mDisPlayHeight = ScreenConstant.SCREEN_HEIGHT;
        mControlView = new ControlView(this, mediatype, controlImp,
                contentView, mDisPlayWidth * 2, (mDisPlayHeight * 2) / 7);
        Log.i(TAG, " mDisPlayWidth" + mDisPlayWidth + "mDisPlayHeight" + mDisPlayHeight);
    }

    protected void showPopUpWindow(final View topview) {
        Looper.myQueue().addIdleHandler(new MessageQueue.IdleHandler() {

            @Override
            public boolean queueIdle() {
                Log.i(TAG, "---------- showPopUpWindow   IdleHandler mControlView:" + mControlView);
                mControlView.showAtLocation(topview,
                        Gravity.LEFT | Gravity.BOTTOM, 0,
                        0);
                // isControlBarShow = true;
                return false;
            }
        });
    }

    private final ControlView.ControlPlayState mControlImp = new ControlView.ControlPlayState() {
        @Override
        public void play() {
            sambaVideoPlayer.play();
        }

        @Override
        public void pause() {
            sambaVideoPlayer.pause();
        }
    };

    public boolean isSmabaPlaying(){
        return sambaVideoPlayer.isSmabaPlaying();
    }

    public void seekTo(long position){
        sambaVideoPlayer.seekTo(position);
    }

    private void removeControlView(){
        if(mControlView != null){
            mControlView.dismiss();
        }
    }

    public void getTrackInfo(){
        Log.d(TAG, "getTrackInfo = " + sambaVideoPlayer.getTrackInfo());
    }



    private IMediaPlayer.OnPreparedListener preparedListener = new IMediaPlayer.OnPreparedListener() {
        @Override
        public void onPrepared(IMediaPlayer iMediaPlayer) {
            Log.d(TAG, "onPrepared");
            iMediaPlayer.start();

            int duration = (int) iMediaPlayer.getDuration();
            Log.d(TAG, "mMediaPlayer.start();"  + "duration" + duration);
            mControlView.setEndtime(duration);
            mControlView.setProgressMax(duration);
            new Thread() {
                public void run() {
                    isplaying = true;
                    while (isplaying) {
                        position = (int)iMediaPlayer.getCurrentPosition();
                        myHandler.sendEmptyMessage(PROGRESS_CHANGE);
                        //Log.d(TAG, "position = " + position);
                        try {
                            Thread.sleep(500);
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }
                    Log.d(TAG, "run = " + position);

                };

            }.start();
        }
    };

}

mediaplayer主要方法就是
mMediaPlayer.setDisplay(surfaceView.getHolder());设置surfaceview
mMediaPlayer.setDataSource(mContext, Uri.parse(mPath));可以是文件路径也可以是URI。
mMediaPlayer.prepareAsync();异步加载。
至此就完成了播放
mediaplayer+surfaceview中mediaplayer不一定非得是meidaplayer,也可以是ijkplayer(bilibili开源视频框架,基于ffmpeg),exoplayer(yutube视频框架)。这两个比mediaplayer更加强大,使用时导入这两个框架即可,使用方法与mediaplayer基本一致。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值