随笔 - 262  文章 - 0  评论 - 5  阅读 - 20万

聊聊视频播放那些事2

MediaPlayer 工作逻辑了解一下

随便画了一下图帮助理解。

打个比喻,mediaplayer 可以为电影播放机。各种view是他的屏幕。回调事件可以理解为电影播放员。

继续聊无逢播放。

第一个页面在播的视频全屏以后或者跳第二页继续无逢播放。

直接的想法是,开始页面播了多少,进到第二页面接着上个播放点继续播。进入第二页后台,初始化mediaPlayer ,setResouce,setSurface ,start,seek到播放点。

会发现这个过程时间很长,转圈圈要好久,这并不是产品经理想要的。

要解决问题

以下内容了解一下。

第一:mediaPlayer应该单例工作。看mediaplayer源码,其中很多功能是natvie实现。他的工作是获取流并解码,形成图像流并展示在界面上。画图像流可以用surface Glsurface textrueView等 。

第二:mediaPlayer应该在线程工作。

第三:回调事件工作在UI线程。

 

试问以下问题。

MediaPlayer开始工作以后,"屏幕能不能换"?

MediaPlayer开始工作以后,"放影人能不能换"?

答案是可以的。

假设使用TextureView作为“银幕”,在场景1使用TextureView1 ,在场景2使用TextureView2,这个操作完全没有问题。

在MediaPlayer开始工作以后,重新设置各种 listener也是没有问题的。

那么:MediaPlayer播放不依赖于UI线路程,page1跳到page2 MediaPlayer播放不停,更换“银幕”和“放影人”就可以。

看效果,贴代码:

复制代码
package com.example.administrator.videotest;

import android.annotation.SuppressLint;
import android.content.Intent;
import android.graphics.SurfaceTexture;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.Surface;
import android.view.TextureView;
import android.view.View;
import android.widget.Button;

public class Main2Activity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);

        Button button = findViewById(R.id.bt);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent i = new Intent(Main2Activity.this, Main3Activity.class);
                startActivity(i);
            }
        });
    }


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

        StaticHolder.textureView = findViewById(R.id.tv);
        StaticHolder.textureView.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() {
            @Override
            public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
                initMediaPlayer(new Surface(surface));
            }

            @Override
            public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {

            }

            @Override
            public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
                return false;
            }

            @Override
            public void onSurfaceTextureUpdated(SurfaceTexture surface) {

            }
        });
    }

    //声明成静态,第二页接着用。
    static public MediaPlayer mediaPlayer;

    @SuppressLint("NewApi")
    public void initMediaPlayer(Surface surface) {
        try {
            mediaPlayer = MediaPlyerHelper.getMediaPlayer();
            mediaPlayer.setSurface(surface);
            mediaPlayer.setOnBufferingUpdateListener(new MediaPlayer.OnBufferingUpdateListener() {
                @Override
                public void onBufferingUpdate(MediaPlayer mp, int percent) {

                }
            });
            mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                @Override
                public void onCompletion(MediaPlayer mp) {
                    mp.start();
                }
            });
            mediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
                @Override
                public boolean onError(MediaPlayer mp, int what, int extra) {
                    return false;
                }
            });

            //AssetFileDescriptor fileDescriptor = getAssets().openFd("sample.mp4");
            mediaPlayer.setDataSource("https://mov.bn.netease.com/open-movie/nos/mp4/2016/01/11/SBC46Q9DV_hd.mp4");
            mediaPlayer.prepare();
            mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                @Override
                public void onPrepared(MediaPlayer mp) {
                    mp.start();
                }
            });


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

    }
}
复制代码
复制代码
package com.example.administrator.videotest;

import android.graphics.SurfaceTexture;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.Surface;
import android.view.TextureView;

public class Main3Activity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main3);
        TextureView rl = findViewById(R.id.tv);
        rl.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() {
            @Override
            public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
                Main2Activity.mediaPlayer.setSurface(new Surface(surface));
            }

            @Override
            public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {

            }

            @Override
            public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
                return false;
            }

            @Override
            public void onSurfaceTextureUpdated(SurfaceTexture surface) {

            }
        });
    }
}
复制代码

 

怎么样基本无逢跳转。

先到这儿下篇更多内容,制作《腾讯新闻》视频列表及相应动画。

 

posted on   wp7ers  阅读(211)  评论(0编辑  收藏  举报
编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示