【Android 多媒体开发】 MediaPlayer 网络视频播放器(一)

简介: 【Android 多媒体开发】 MediaPlayer 网络视频播放器(一)

一. 相关模块解析





1. 播放载体 SurfaceView 简介





(1) SurfaceView 与 Surface



SurfaceView 与 Surface 简介 : SurfaceView 中嵌入了一个 Surface, SurfaceView 可以操控 Surface 的 位置, 大小尺寸等;


-- SurfaceView 绘制图像可见性 : Surface 相当与一块画板, 上面绘制了一些东西, 但是不是所有的内容都可见, SurfaceView 相当与 Surface 的窗口, 只有在 SurfaceView 窗口区域内的才是可见的, 其它没有在窗口正下方的内容不可见;


-- Surface 与 SurfaceView 声明周期对应 : SurfaceView 可见的时候 Surface 被创建, SurfaceView 不可见时 Surface 销毁, Surface 创建销毁时机回调方法 SurfaceCreated(SurfaceHolder) 和 SurfaceDestoryed(SurfaceHolder) 方法, 这两个回调方法是 SurfaceHolder.Callback 中设定;


-- Surface 控制 : SurfaceView 通过 SurfaceHolder 控制 Surface;






(2) SurfaceHolder 简介



Surfaceholder 简介 : SurfaceHolder 是 Surface 的控制器, 用于控制 SurfaceView 绘图, 处理画布上的 动画 渲染效果 尺寸等;


-- 添加 Callback 回调接口 : abstract void addCallback(SurfaceHolder.Callback callback), 添加一个 SurfaceHolder.Callback 接口对象, 监听 Surface 的开始结束绘制大小改变事件;


-- 锁定画布 :  abstract Canvas lockCanvas(), 锁定画布, 可以获得 Canvas 对象, 之后就可以在 Canvas 上绘图了;




(3) SurfaceHolder.Callback 简介



SurfaceHolder.Callback 接口 :


-- Surface 绘图边界 : 所有的绘图操作, 在 Surface 创建后操作, 在 Surface 销毁之前结束;


-- SurfaceHolder.Callback 接口对应 Surface 边界 : SurfaceCreated() 方法在 Surface 创建时回调, SurfaceDestroyed() 方法在 Surface 销毁前回调;




SurfaceHolder.Callback 接口中的方法简介 :


-- SurfaceChanged() : Surface 大小改变前回调;


-- surfaceCreated() : surface 创建时回调;


-- surfaceDestroyed() : surface 销毁时回调;






2. SurfaceView 使用流程





(1) 在布局文件中使用 SurfaceView 组件



布局文件 : 在布局文件中使用  组件;


-- 示例 :



<SurfaceView 
        android:id="@+id/surface_view"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="3"/>



(2) 设置 SurfaceHolder.Callback 回调接口



创建回调接口子类 : Activity 继承 SurfaceHolder.Callback 接口, 实现接口的三个方法 SurfaceCreated(), SurfaceChanged(), SurfaceDestroyed() 方法;


-- 示例 : 一般情况下直接设置 Activity 实现该接口, 为 SurfaceHolder 设置接口的时候直接将 Activity 设置进去;



public class HomeActivity extends Activity implements SurfaceHolder.Callback {
  /**
  * 在 Surface 大小发生改变的时候回调
  * 实现的 SurfaceHolder.Callback 接口方法
  */
  @Override
  public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
  System.out.println("SurfaceHolder.Callback.surfaceChanged : Surface 大小发生改变");
  }
  /**
  * 在 Surface 创建的时候回调, 一般在该方法中开始绘图
  * 实现的 SurfaceHolder.Callback 接口方法
  */
  @Override
  public void surfaceCreated(SurfaceHolder arg0) {
  System.out.println("SurfaceHolder.Callback.surfaceCreated : Surface 开始创建");
  }
  /**
  * 在 Surface 销毁之前回调, 在该方法中停止渲染线程, 释放相关资源
  * 实现的 SurfaceHolder.Callback 接口方法
  */
  @Override
  public void surfaceDestroyed(SurfaceHolder arg0) {
  System.out.println("SurfaceHolder.Callback.surfaceDestroyed : Surface 销毁");
  }
}



(3) 获取 SurfaceHolder 对象 并添加回调接口子类



获取 SurfaceHolder 流程 :


-- a. 获取 SurfaceView : 使用 findViewById() 方法从布局文件中获取 SurfaceView 组件对象;



surface_view = (SurfaceView) findViewById(R.id.surface_view);

-- b. 从 SurfaceView 组件对象中获取 SurfaceHolder : 调用 SurfaceView 对象的

getHolder() 即可获取 SurfaceHolder 对象;
surface_holder = surface_view.getHolder();      /* 根据 SurfaceView 组件, 获取 SurfaceHolder 对象 */

-- c. 为 SurfaceHolder 设置回调接口 : 调用 Surfaceholder 的 setCallback() 方法即可, 用于监听 Surface 的创建 改变 和 销毁;


surface_holder.addCallback(this);         /* 为 SurfaceHolder 设置回调函数, 即 SurfaceHolder.Callback 子类对象 */

SurfaceHolder 其它设置 :


-- 设置 SurfaceHolder 画面比例 : 调用 SurfaceHolder 的 setFixedSize() 方法;



surface_holder.setFixedSize(160, 128);        /* 设置视频大小比例 */

-- 设置 SurfaceHolder 数据类型 : 调用 SurfaceHolder 的 setType() 方法;


surface_holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);/* 设置视频类型 */


总体代码示例 :



/**
  * 初始化相关数据变量
  */
  private void initData() {
  /* 获取并设置 SurfaceHolder 对象 */
  surface_holder = surface_view.getHolder();      /* 根据 SurfaceView 组件, 获取 SurfaceHolder 对象 */
  surface_holder.addCallback(this);         /* 为 SurfaceHolder 设置回调函数, 即 SurfaceHolder.Callback 子类对象 */
  surface_holder.setFixedSize(160, 128);        /* 设置视频大小比例 */
  surface_holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);/* 设置视频类型 */
  }





3. AutoCompleteTextView 组件



组件特性 : 可以设置一个适配器, 适配器中维护一组字符串, 当输入一部份字符后, 能 自动将符合条件的提示出来;


-- 示例 :

image.png






(1) 在布局文件中定义组件



布局文件中 : 使用  标签添加组件;


-- 设置后面省略 : android:ellipsize="end" , 由于链接太长, 不能显示全部, 自动将后面的部分省略;


-- 设置提示 : android:completionHint="选择下载的视频地址", 设置弹出的提示栏最后一栏的提示;


-- 设置单行显示 : android:singleLine="true";


-- 设置输入几个字符之后开始提示 : android:completionThreshold="1", 这里设置的是输入第一个字符之后就开始自动提示;


-- 示例 :



<AutoCompleteTextView 
        android:id="@+id/url"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:singleLine="true"
        android:ellipsize="end"
        android:completionThreshold="1"
        android:text="http://daily3gp.com/vids/747.3gp"
        android:completionHint="选择下载的视频地址"/>


(2) 创建适配器



创建适配器方法 :


android.widget.ArrayAdapter.ArrayAdapter<String>(Context context, int textViewResourceId, String[] objects)

-- Context context 参数 : 上下文对象;

-- int textViewResourceId 参数 : 显示列表的组件的布局;


-- String[] objects 参数 : 字符串数组对象;




代码示例 :



/* 设置一个列表适配器 */
  String[] urls = {
    "http://daily3gp.com/vids/747.3gp",
    "http://daily3gp.com/vids/Funny%20women%20cannot%20understand.3gp",
    "http://k.youku.com/player/getFlvPath/sid/9409280845322127f6c57_00/st/flv/fileid/0300020100540024BC9E5C08BD8A98D8200E2B-7950-B9A5-8669-DC283BDCC077?K=3a58dc2cdcc532df261dddec&ctype=12&ev=1&oip=1931322792&token=5696&ep=eyaUE0uFVsYE4CDdij8bYHrkJ3IIXP4J9h%2BFg9JjALshTOi%2FmzqjtJTFS4xCHottelMPGJ%2F5qdDnH0JmYfdKrGgQrUfZPPro%2BPbq5dkgxpgDFG1FAc3Qs1SbRTn3",
    "http://k.youku.com/player/getFlvPath/sid/9409280845322127f6c57_00/st/flv/fileid/030002040053FFB59E433100422C39BAFA46CC-4DED-E928-87B8-91706CDB5FF2?K=645d8478a3aa59052411eb8a&ctype=12&ev=1&oip=1931322792&token=5696&ep=eyaUE0uFVsYE4CDdij8bYHrkJ3IIXP4J9h%2BFg9JmALshS57J6zvYspmzTf5CFv0bcFEFGZmA3aHjbDNnYfQ33BwQqkeqMfro%2BYLr5aRSw5AGFW1Ed7uhtlSbRTn3"
  };
  /* 创建数组适配器 */
  ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, 
    android.R.layout.simple_dropdown_item_1line, urls);
  /* 将适配器设置给 AutoCompleteTextView 组件对象 */
  url.setAdapter(adapter);
目录
相关文章
|
6月前
|
XML 缓存 Android开发
Android开发,使用kotlin学习多媒体功能(详细)
Android开发,使用kotlin学习多媒体功能(详细)
148 0
|
9天前
|
Linux 开发工具 Android开发
FFmpeg开发笔记(六十)使用国产的ijkplayer播放器观看网络视频
ijkplayer是由Bilibili基于FFmpeg3.4研发并开源的播放器,适用于Android和iOS,支持本地视频及网络流媒体播放。本文详细介绍如何在新版Android Studio中导入并使用ijkplayer库,包括Gradle版本及配置更新、导入编译好的so文件以及添加直播链接播放代码等步骤,帮助开发者顺利进行App调试与开发。更多FFmpeg开发知识可参考《FFmpeg开发实战:从零基础到短视频上线》。
56 2
FFmpeg开发笔记(六十)使用国产的ijkplayer播放器观看网络视频
|
5天前
|
Java 程序员 开发工具
Android|修复阿里云播放器下载不回调的问题
虽然 GC 带来了很多便利,但在实际编码时,我们也需要注意对象的生命周期管理,该存活的存活,该释放的释放,避免因为 GC 导致的问题。
15 2
|
5月前
|
XML 存储 数据库
如何使用Android Studio创建一个基本的音乐播放器应用
如何使用Android Studio创建一个基本的音乐播放器应用
201 0
|
3月前
|
编解码 开发工具 Android开发
Android平台RTSP|RTMP播放器如何实现TextureView渲染
本文介绍了在Android平台上使用TextureView进行RTSP和RTMP视频流渲染的技术背景和实现方法。TextureView相较于SurfaceView具备更高性能、更强功能性和更灵活的绘制方式等优势,但也有必须在硬件加速环境下运行和较高内存占用等局限。文中详细展示了如何在SmartPlayerV2工程中创建和配置TextureView,并通过代码示例解释了如何根据视频分辨率信息调整显示比例,以及处理TextureView的各种生命周期回调。此外,还列举了该播放器SDK支持的多项高级功能,如多实例播放、多种编码格式支持、硬解码能力等,旨在帮助开发者更好地理解和实现高性能的直播播放器。
|
3月前
|
算法 数据处理 开发工具
Android平台RTSP|RTMP播放器如何回调YUV或RGB数据
在开发Android平台上的RTSP或RTMP播放器时,开发者不仅追求低延迟播放,还希望获取解码后的视频数据(如YUV或RGB格式),以便进行视觉算法分析。使用大牛直播SDK中的SmartPlayer,可在确保播放流畅的同时,通过设置外部渲染器(`SmartPlayerSetExternalRender`)来高效地回调原始视频数据。例如,对于RGBA数据,需实现`NTExternalRender`接口,并重写相关方法以处理数据和尺寸变化。同样地,对于I420(YUV)数据,也需要相应地实现接口以满足需求。这种方式使得开发者能在不影响常规播放功能的情况下,进行定制化的视频处理任务。
|
3月前
|
编解码 网络协议 开发工具
Android平台RTSP|RTMP直播播放器技术接入说明
大牛直播SDK自2015年发布RTSP、RTMP直播播放模块,迭代从未停止,SmartPlayer功能强大、性能强劲、高稳定、超低延迟、超低资源占用。无需赘述,全自研内核,行业内一致认可的跨平台RTSP、RTMP直播播放器。本文以Android平台为例,介绍下如何集成RTSP、RTMP播放模块。
143 0
|
5月前
|
前端开发 Java 关系型数据库
基于JSP技术的网络视频播放器
基于JSP技术的网络视频播放器
|
5月前
|
API Android开发 UED
56. 【Android教程】媒体播放器:MediaPlayer
56. 【Android教程】媒体播放器:MediaPlayer
91 0
|
6月前
|
存储 Web App开发 编解码
计算机网络——多媒体网络
计算机网络——多媒体网络