聊聊视频播放那些事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) {

            }
        });
    }
}

怎么样基本无逢跳转。

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

原文地址:https://www.cnblogs.com/mamamia/p/9480920.html

时间: 2024-08-30 02:47:32

聊聊视频播放那些事2的相关文章

评论精选:聊聊创业那些事

创业无论在什么时候都是一个很热门的话题.很多人都是对创业充满着无限的向往,那么创业是为了什么呢? 1.为了自由 2.为了"梦想" 3.因为不想打工(or找不到工作) 4.为了赚钱. 5.因为创业比较热门 我们每个人想要创业的目的都是不尽相同,那么要怎么看待创业呢?创业简单吗?看看网友的犀利见解. 在家赚钱的十种方法:我相信在中国,每一个人都有一个创业梦,事实上创业也非常简单,但是我问大家你借过钱吗?有过还不起钱想逃避的经历吗?我相信每一个人都有,那种滋味和压力不好受吧?但如果你要做老板

一起聊聊“事务”那些事

事务的概念 1.          事务可以看作是由对数据库的若干操作组成的一个单元,这个单元是一个整体,该整体具有高度集体责任感.荣誉感,执行操作时要么都成功,要么都失败,从而保证数据满足一致性的要求: 2.          事务处理是所有大型数据库产品的一个关键问题,各数据库厂商都在这个方面花费了很大精力,不同的事务处理方式会导致数据库性能和功能上的巨大差异. 事务的例子 1.     银行转账:帐户A把一定数量的款项转到帐户B上,这个操作包括两个步骤,一个是从帐户A上把存款减去一定数量,

Nginx的负载均衡的那点事 (转)

本节就聊聊采用Nginx负载均衡之后碰到的问题: Session问题 文件上传下载 通常解决服务器负载问题,都会通过多服务器分载来解决.常见的解决方案有: 网站入口通过分站链接负载(天空软件站,华军软件园等) DNS轮询 F5物理设备 Nginx等轻量级架构 那我们看看Nginx是如何实现负载均衡的,Nginx的upstream目前支持以下几种方式的分配 1.轮询(默认) 每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除. 2.weight 指定轮询几率,wei

安全狗路演·杭州站

在互联网+时代,不管是电商.P2P.还是游戏行业,创业的热情已经被完全点燃,然而,但是我们常常忽视了创业和奋斗途中一个重要的问题--网络安全.国内知名安全品牌,安全狗将携著名神秘黑客空降杭州楼友会咖啡,与初创者以及广大安全爱好者共同聊聊安全那些事. 这里有成功的创业者,这里有顶尖的企业家,这里有资深的安全专家,这里有专业的安全架构师......只要你敢问,没有我们不能答:只要你想知道,没有我们不能回. "无创业 不安全",安全狗让创业更简单,让创业更安全!同时我们还为现场的朋友们准备了

单身男生必备知识2

有人可能会说,动物是动物,人是人,完全是两码事.我告诉你,武则天在当女皇之前,可是一个驯马高手,她之所以能君临天下,就是她用驯马的那一套用来训人,起到了非常好的效果.其实人在很多时候,和动物一样,都有抹不去的动物本能. ######################################## 到底谁才是那个值得你爱的人?当一个男生同时喜欢上两个女孩时,这个男生会更喜欢谁一些?可能许多人都会对这个问题展开讨论,可能会觉得哪个女孩更优秀,哪个女孩就会得到更多的爱.现实中难道真的是这样的吗?当

关于Python编程的一些问答

关于Python编程的一些问答 导语 大约1个月前,oschina.net和华章图书一起合作做了一个活动:OSC第51期高手问答--聊聊python那些事,来推广我参与撰写的书<编写高质量代码:改善Python程序的91个建议>(豆瓣链接).在回答问题的过程中,我看到有若干问题是好几个人都问了的,就萌发了在事后把这些问答整理整理的想法,以下内容就是来自那一次的问答.为简化整理,已经去掉了提问人的昵称,并做了简单的分类. 纠结的Py2与Py3之选 Q:Python 3 会导致Python的什么前

扩展方法从简单应用到深入解析,读这一篇文章就够了

前言(扯淡-_-) 大家好,今天和大家聊聊扩展的事,我将带着大家从简单应用开始深入理解扩展方法的原理,并对扩展方法的使用给出合理的建议. 在实际应用中,当我们在使用某类时发现类中缺少我们想要的方法,最简单直接的就是修改类的源代码来添加我们想要的方法.但事实往往不如人意,总会因为各种因素不可以直接修改源码:拿不到源码.不允许修改,这时候通过继承并扩展的方式来复用是再好不过了,但是如果连最后的继承的权利都剥夺的话(密封类不允许继承)?...这时候就需要用到[扩展方法]了. 扩展方法简介 我们先来看看

如何在大公司好好发挥自己的才能

本文为<启示录>的读书笔记,原为「在大公司施展拳脚十大秘诀」的章节章节内容,原文主要介绍了产品经理与大公司的合作经验,但是我觉得里面介绍的经验不单适合产品经理,同时也适合所有来到大公司的新人们,所以跟大家分享一下. 首先,大公司都遵循一条潜规——尽量规避风险.这并非偶然,随着业务规模变大,公司会不可避免地变得保.因为大公司承担的风险更大,如果出现问题,损失也比小公司惨重.所以创新更容易发生在小公司里.在大公司工作,首先要面对的是公司现有的流程.规定和条条框框. 其次,多数大公司都采取矩阵式的管

【文学文娱】《致青春--我的大学(吉林大学)》

本文地址 原文地址--微信 点击关注 微信公众号 概述--吉大好大啊 上过大学的人,对自己的大学都有比较深厚的情感,我也不例外.尤其是毕了业工作了的人,想起自己四年的大学,总是忍不住的想念.我就是这样,趁着今天北京的天气不错,雾霾少,我也来回一下那些的四年我是怎么过来的. 吉大·风景如画,至今怀念 我的大学在白山黑水间,四季如春的长春(哈哈,长春嘛).之所以选择在了冰天雪地的大东北,主要是因为我个人比较喜欢东北人的豪爽和幽默,本山大叔的小品我是看着长大的,所以感情还是有的.想过去杏花春雨的江南的