Android視頻直播源碼中如何實現無縫切碼流

package com.example.hejunlin.seamlessvideo;

import android.annotation.TargetApi;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.pm.PackageManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnPreparedListener;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.Gravity;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.FrameLayout;

import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;

/**
 * 兼容8.0版本
 */
public class MainActivity extends AppCompatActivity {

    private SurfaceView mVideoSurface, mNextSurface;
    private FrameLayout mFrame;
    private MediaPlayer mCurrentMediaPlayer, mNextMediaPlayer;
    private Handler mHandler;
    private int mIndex = 0;
    private String path1 = Environment.getExternalStorageDirectory().getAbsolutePath() + "/1.mp4";
    private String path2 = Environment.getExternalStorageDirectory().getAbsolutePath() + "/2.mp4";
    private String[] paths = new String[]{path1, path2};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (!checkPermission()) {
            startAction();
        } else {
            if (checkPermission()) {
                requestPermissionAndContinue();
            } else {
                startAction();
            }
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mHandler.removeCallbacks(mPlayRun);
        if (mCurrentMediaPlayer != null) {
            mCurrentMediaPlayer.release();
            mCurrentMediaPlayer = null;
        }
        if (mNextMediaPlayer != null) {
            mNextMediaPlayer.release();
            mNextMediaPlayer = null;
        }
    }

    Runnable mPlayRun = new Runnable() {

        @Override
        public void run() {
            Log.d(MainActivity.class.getSimpleName(), "run: ");
            mCurrentMediaPlayer.pause();
            mNextMediaPlayer.pause();
            mNextMediaPlayer.reset();

            try {
                if (mIndex == 0) {
                    String path = paths[mIndex % paths.length];
                    Log.d(MainActivity.class.getSimpleName(), "path1: " + path);
                    mIndex++;
                    mCurrentMediaPlayer.setDataSource(MainActivity.this, Uri.parse(path));
                    mCurrentMediaPlayer.setOnPreparedListener(new OnPreparedListener() {

                        @Override
                        public void onPrepared(MediaPlayer player) {
                            Log.d(MainActivity.class.getSimpleName(), "start 1");
                            mCurrentMediaPlayer.start();
                            mVideoSurface.setVisibility(View.GONE);
                        }
                    });
                    mCurrentMediaPlayer.prepareAsync();

                    mNextMediaPlayer.setDataSource(MainActivity.this, Uri.parse(path));
                    mNextMediaPlayer.setOnPreparedListener(new OnPreparedListener() {

                        @Override
                        public void onPrepared(MediaPlayer arg0) {
                            mNextMediaPlayer.start();
                        }
                    });
                    mNextMediaPlayer.prepareAsync();
                } else {
                    String path = paths[mIndex % paths.length];
                    mIndex++;
                    Log.d(MainActivity.class.getSimpleName(), "path2: " + path);
                    mNextMediaPlayer.setDataSource(MainActivity.this, Uri.parse(path));
                    mNextMediaPlayer.setOnPreparedListener(new OnPreparedListener() {

                        @Override
                        public void onPrepared(MediaPlayer arg0) {
                            mNextMediaPlayer.start();
                            Log.d(MainActivity.class.getSimpleName(), "start 2");
                        }
                    });
                    mNextMediaPlayer.prepareAsync();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }

            mHandler.postDelayed(mPlayRun, 10000); // 第一個視頻10s鍾
        }

    };

    class VideoSurfaceHodlerCallback implements SurfaceHolder.Callback {

        @Override
        public void surfaceChanged(
                SurfaceHolder holder,
                int format, int width, int height) {

        }

        @Override
        public void surfaceCreated(SurfaceHolder holder) {
            mCurrentMediaPlayer.setDisplay(mVideoSurface.getHolder());
        }

        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {

        }

    }

    class NextVideoSurfaceHodlerCallback implements SurfaceHolder.Callback {

        @Override
        public void surfaceChanged(
                SurfaceHolder holder,
                int format, int width, int height) {

        }

        @Override
        public void surfaceCreated(SurfaceHolder holder) {
            mNextMediaPlayer.setDisplay(mNextSurface.getHolder());
        }

        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {

        }

    }

    private static final int PERMISSION_REQUEST_CODE = 200;
    private boolean checkPermission() {

        return ContextCompat.checkSelfPermission(this, WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
                && ContextCompat.checkSelfPermission(this, READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
                ;
    }

    private void requestPermissionAndContinue() {
        if (ContextCompat.checkSelfPermission(this, WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
                && ContextCompat.checkSelfPermission(this, READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {

            if (ActivityCompat.shouldShowRequestPermissionRationale(this, WRITE_EXTERNAL_STORAGE)
                    && ActivityCompat.shouldShowRequestPermissionRationale(this, READ_EXTERNAL_STORAGE)) {
                AlertDialog.Builder alertBuilder = new AlertDialog.Builder(this);
                alertBuilder.setCancelable(true);
                alertBuilder.setTitle("權限申請");
                alertBuilder.setMessage("獲取對應權限");
                alertBuilder.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
                    @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
                    public void onClick(DialogInterface dialog, int which) {
                        ActivityCompat.requestPermissions(MainActivity.this, new String[]{WRITE_EXTERNAL_STORAGE
                                , READ_EXTERNAL_STORAGE}, PERMISSION_REQUEST_CODE);
                    }
                });
                AlertDialog alert = alertBuilder.create();
                alert.show();
                Log.e("", "permission denied, show dialog");
            } else {
                ActivityCompat.requestPermissions(MainActivity.this, new String[]{WRITE_EXTERNAL_STORAGE,
                        READ_EXTERNAL_STORAGE}, PERMISSION_REQUEST_CODE);
            }
        } else {
            startAction();
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        if (requestCode == PERMISSION_REQUEST_CODE) {
            if (permissions.length > 0 && grantResults.length > 0) {

                boolean flag = true;
                for (int i = 0; i < grantResults.length; i++) {
                    if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {
                        flag = false;
                    }
                }
                if (flag) {
                    startAction();
                } else {
                    finish();
                }

            } else {
                finish();
            }
        } else {
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }

    private void startAction() {
        mFrame = new FrameLayout(this);
        setContentView(mFrame);
        mHandler = new Handler();

        mCurrentMediaPlayer = new MediaPlayer();
        mNextMediaPlayer = new MediaPlayer();

        mVideoSurface = new SurfaceView(this);
        mVideoSurface.getHolder().addCallback(new VideoSurfaceHodlerCallback());

        mNextSurface = new SurfaceView(this);
        mNextSurface.getHolder().addCallback(new NextVideoSurfaceHodlerCallback());

        FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(
                1080,
                1920);
        lp.gravity = Gravity.LEFT | Gravity.TOP;
        mVideoSurface.setLayoutParams(lp);

        lp = new FrameLayout.LayoutParams(
                1080,
                1920);
        lp.gravity = Gravity.LEFT | Gravity.TOP;
        mNextSurface.setLayoutParams(lp);

        mFrame.addView(mNextSurface);
        mFrame.addView(mVideoSurface);
        mHandler.postDelayed(mPlayRun, 0);
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章