視頻播放

學(xué)習(xí)目標(biāo):
Android視頻播放功能在Android應(yīng)用場景(掌握)
視頻播放第一種方式使用系統(tǒng)自帶的播放器(掌握)
視頻播放第二種方式使用VideoView結(jié)合MediaController來播放視頻(掌握)
視頻播放第三種方式使用MediaPlayer類和SurfaceView來實現(xiàn)(掌握)
三種播放視頻方式的分析對比(掌握)
播放視頻資源的格式限制(掌握)
獲取視頻的第一幀

一.在Android中,我們有三種方式來實現(xiàn)視頻的播放:

1、使用其自帶的播放器。指定Action為ACTION_VIEW,Data為Uri,Type為其MIME類型。

2、使用VideoView來播放。在布局文件中使用VideoView結(jié)合MediaController來實現(xiàn)對其控制。

3、使用MediaPlayer類和SurfaceView來實現(xiàn),這種方式很靈活。

本地資源

內(nèi)部URI,比如你可以通過ContentResolver來獲取

外部URL(流)

二.第一種方式--使用系統(tǒng)自帶的播放器

Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.parse(vedios[0]), "video/mp4");
startActivity(intent);

三.第二種方式--使用VideoView結(jié)合MediaController來播放視頻

1.布局中添加VideoView

 <VideoView
        android:id="@+id/vv_vv"
        android:layout_width="wrap_content"
        android:layout_height="100dp"/>

2.具體代碼

  MediaController mediaController = new MediaController(this);
        vv_vv.setMediaController(mediaController);
        vv_vv.setVideoPath(videos[i]);
        vv_vv.start();
        mediaController.setPrevNextListeners(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //下一個
                i++;
                if (i > videos.length - 1) {
                    i = 0;
                }
                vv_vv.setVideoPath(videos[i]);
                vv_vv.start();
            }
        }, new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //上一個
                i--;
                if (i < 0) {
                    i = videos.length - 1;
                }
                vv_vv.setVideoPath(videos[i]);
                vv_vv.start();
            }
        });

四.第三種方式--使用MediaPlayer類和SurfaceView來實現(xiàn)

  • MediaPlayer主要用于播放音頻,沒有提供圖像輸出界面,所以我們需要借助其他的組件來顯示MediaPlayer播放的圖像輸出,我們可以使用SurfaceView來顯示

a.調(diào)用player.setDataSource()方法設(shè)置要播放的資源,可以是文件、文件路徑、或者URL。

b.調(diào)用player.setDisplay(holder)設(shè)置surfaceHolder,surfaceHolder可以通過surfaceview的getHolder()方法獲得。

c.調(diào)用MediaPlayer.prepare()來準(zhǔn)備。

d.調(diào)用MediaPlayer.start()來播放視頻。

  1. 布局中添加SurfaceView
<SurfaceView
        android:id="@+id/sv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

2.具體代碼

public class MpActivity extends AppCompatActivity implements View.OnClickListener {

    private SurfaceView sv;
    private String path;
    private Button btn_pause;
    private Button btn_stop;
    private Button btn_goon;
    private MediaPlayer mediaPlayer;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_mp);
        path = getIntent().getStringExtra("path");
        initView();
    }

    private void initView() {
        sv = (SurfaceView) findViewById(R.id.sv);
        btn_pause = (Button) findViewById(R.id.btn_pause);
        btn_pause.setOnClickListener(this);
        btn_stop = (Button) findViewById(R.id.btn_stop);
        btn_stop.setOnClickListener(this);
        btn_goon = (Button) findViewById(R.id.btn_goon);
        btn_goon.setOnClickListener(this);

        try {
            mediaPlayer = new MediaPlayer();
            mediaPlayer.setDataSource(path);
            mediaPlayer.prepare();

            //必須在界面渲染的時候添加,不能在點擊事件中
            SurfaceHolder surfaceHolder = sv.getHolder();
            surfaceHolder.addCallback(new SurfaceHolder.Callback() {
                @Override
                public void surfaceCreated(SurfaceHolder holder) {
                    mediaPlayer.setDisplay(holder);
                }

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

                }

                @Override
                public void surfaceDestroyed(SurfaceHolder holder) {

                }
            });

            mediaPlayer.start();

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_pause:
                mediaPlayer.pause();
                break;
            case R.id.btn_stop:
                mediaPlayer.stop();
                break;
            case R.id.btn_goon:
                mediaPlayer.start();
                break;
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mediaPlayer.stop();
    }
}

五.三種播放視頻方式的分析對比

  1. android SDK自帶的 MediaPlayer+SurfaceView或者videoview (簡單快速,格式支持少)

  2. MediaPlayer類是Androd多媒體框架中的一個重要組件,通過該類,我們可以以最小的步驟來獲取,解碼和播放音視頻。它支持三種不同的媒體來源:
    在播放網(wǎng)絡(luò)上的視頻流時,Android原生的MediaPlayer支持兩種協(xié)議,HTTP和RTSP,這兩種協(xié)議最大的不同是,RTSP協(xié)議支持實時流媒體的播放,而HTTP協(xié)議不支持。因為VideoView的底層實現(xiàn)是MediaPlayer,因此VideoView也支持以上兩種協(xié)議。 但是Android原生MediaPalyer支持的協(xié)議(不支持RTMP、MMS等)和封裝格式實在太有限了,如果我們想播放那些它不支持的視頻,這時候就需要第三方播放器了,很多第三方播放器的底層實現(xiàn)都是基于FFmpeg,后續(xù)我會專門來講講第三方播放器和FFmpeg的使用。

  3. MediaPlayer主要用于播放音頻,沒有提供圖像輸出界面,所以我們需要借助其他的組件來顯示MediaPlayer播放的圖像輸出,我們可以使用SurfaceView來顯示。

  4. 除了使用MediaPlayer + SurfaceView播放視頻的方式,我們還可以使用VideoView來直接播放視頻。

  5. SurfaceView播放視頻時,如果不進(jìn)行設(shè)置,視頻寬高總是等于定義的SurfaceView布局寬高,所以視頻可能會被拉伸變形。而使用VideoView時,視頻寬度等于VideoView布局寬,但是高是自適應(yīng)的,自動調(diào)整寬高比到視頻原始比例,所以不會有拉伸。

  6. 本地資源,內(nèi)部URI,比如你可以通過ContentResolver來獲取,外部URL(流)

六.播放視頻資源的格式限制

Android官方公布的文檔顯示MediaPlayer支持如下視頻格式:

H.263 X X 3GPP (.3gp)
MPEG-4 (.mp4)?
H.264 AVC X 3GPP (.3gp)
MPEG-4 (.mp4)?
MPEG-4 SP X
3GPP (.3gp)

這些格式的視頻,基本上屬于手機(jī)支持的視頻格式。如果想觀看其他類型格式的視頻,比如flv等,需要下載暴風(fēng)、迅雷等播放器。

七.三方視頻庫

  1. Vitamio
    Vitamio 是一款 Android與 iOS平臺上的全能多媒體開發(fā)框架,全面支持硬件解碼與 GPU渲染。Vitamio憑借其簡潔易用的 API接口贏得了全球眾多開發(fā)者的青睞。到目前,全球已經(jīng)有超過 1800種應(yīng)用在使用 Vitamio,覆蓋用戶超過 2億。

    Vitamio 能夠流暢播放720P甚至1080P高清MKV,F(xiàn)LV,MP4,MOV,TS,RMVB等常見格式的視頻,還可以在 Android 與iOS上跨平臺支持 MMS, RTSP,RTMP, HLS(m3u8)等常見的多種視頻流媒體協(xié)議,包括點播與直播。

    目前Vitamio的項目托管在Github上面:https://github.com/yixia

  2. JiaoZiVideoPlayer(以前叫節(jié)操播放器)
    節(jié)操播放器

  3. ijkplayer
    項目地址
    介紹:Ijkplayer 是Bilibili發(fā)布的基于 FFplay 的輕量級 Android/iOS 視頻播放器。實現(xiàn)了跨平臺功能,API 易于集成;編譯配置可裁剪,方便控制安裝包大??;支持硬件加速解碼,更加省電;提供 Android 平臺下應(yīng)用彈幕集成的解決方案。

  1. 這里還有很多

八.獲取視頻的第一幀

MediaMetadataRetriever retriever = new MediaMetadataRetriever();
retriever.setDataSource(data);
 //timeUs 微秒
 //option
 //OPTION_CLOSEST    在給定的時間,檢索最近一個幀,這個幀不一定是關(guān)鍵幀。
 //OPTION_CLOSEST_SYNC   在給定的時間,檢索最近一個同步幀(關(guān)鍵幀)。
 //OPTION_NEXT_SYNC 在給定時間之后檢索一個同步幀(關(guān)鍵幀)。
 //OPTION_PREVIOUS_SYNC  在給定時間之前檢索一個同步幀(關(guān)鍵幀)
Bitmap frameAtTime = retriever.getFrameAtTime(7000*1000, MediaMetadataRetriever.OPTION_CLOSEST);

mIv.setImageBitmap(frameAtTime);

九.橫豎屏切換

  /**

 * 切換橫豎屏

 */

 private void switchScreen() {

 /*if (現(xiàn)在是橫屏){

 //切換豎屏

 }else {

 //切換成橫屏

 }*/

 ///切換屏幕的時候,Activity會重建,怎么解決

 //在清單文件配置一下就ok,

 //獲取當(dāng)前屏幕方向

 int requestedOrientation = getRequestedOrientation();

 if (requestedOrientation == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE){

 //橫屏,切換豎屏

 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

 }else {

 //切換成橫屏

 setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

 }

 }

  //screensize,屏幕大小發(fā)生改變;

 //orientation屏幕方向發(fā)生改變

 //keyboardHidden鍵盤隱藏

 -->

 <activity

 android:name=".VideoViewActivity"

 android:configChanges="screenSize|orientation|keyboardHidden" />
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容