Android -- 多媒体播放之MediaPlayer基础简介

Android 9.0 MediaPlayer播放流程分析 MediaPlayer流程分析 阅读详情

Android -- MediaPlayer基础简介


MediaPlayer是Android中的一个多媒体播放类,我们能通过它控制音视频流或本地音视频资源的播放过程。

这段时间查阅了Android官方文档对MediaPlayer的介绍,同时也看了一些书籍介绍。现在把MediaPlayer的基础内容在此做一个记录,以供后面查阅、回忆。


MediaPlayer系统的主要代码实现介绍如下:


1、Java部分

MediaPlayer.java

Java类主要的路径在\frameworks\base\media\java\android\media\MediaPlayer.java

2、Native部分

MediaPlayer.java中的功能实现都借助JNI调到Native层,JNI主要实现在\frameworks\base\media\jni\android_media_MediaPlayer.cpp,这部分编译会得到libmedia_jni.so库。
多媒体底层库的代码实现主要在\frameworks\av\media\libmedia\目录下,这部分编译得到的是libmedia.so库。
最后多媒体服务部分的代码实现主要在\frameworks\av\media\libmediaplayerservice\目录下,这部分编译得到的是libmediaplayerservice.so库。

这三个库的调用关系如图所示:MediaPlayer.java -> libmedia_jni.so -> libmedia.so -> libmediaplayerservice.so.


下图是一个MediaPlayer对象被支持的播放控制操作驱动的声明周期和状态。其中,椭圆代表MediaPlayer可能驻留的状态,弧线表示驱动MediaPlayer在各个状态之间迁移的播放控制操作。这里有两种类型的弧线。由单箭头开始的弧线代表同步方法调用,而以双箭头开头的弧线代表异步方法调用。图片介绍来源于官方文。



通过上图,我们知道一个MediaPlayer对象有如下几种状态。

  1. 当一个MediaPlayer对象被刚刚用new操作符或者是调用了reset()方法后,就处于Idle状态。当调用了release()方法后,处于End状态。这两种状态之间是MediaPlayer对象的生命周期。
     在一个新构建的MediaPlayer对象和一个调用了reset()方法的MediaPlayer对象之间有一个微小但十分重要的差别。当处于Idle状态时,调用 getCurrentPosition(), getDuration(), getVideoHeight(), getVideoWidth(), setAudioStreamType(int), setLooping(boolean), setVolume(float, float), pause(), start(), stop(), seekTo(int), prepare() or prepareAsync()方法都是错误的。当一个MediaPlayer对象刚被创建时,内部的播放引擎和对象的状态都没有改变,这时调用以上方法,框架无法回应客户端程序注册的OnErrorListener.onError()方法;但若这个对象调用了reset()方法后,再调用以上方法,内部的播放引擎就会回调客户端程序注册的OnErrorListener.onError()方法,并将错误的状态传入。
当一个MediaPlayer对象不再被使用时,应立即调用release()方法来释放在内部的播放引擎与这个MediaPlayer对象关联的资源。资源可能包括硬件加速组件的单态固件,若没有调用release()方法可能会导致之后的MediaPlayer对象实例无法使用这种单态硬件资源,从而导致程序异常。一旦MediaPlayer对象进入了End状态,将不能再被使用,也没有办法再迁移到其他状态。
此外,使用new操作符创建的MediaPlayer对象处于Idle状态,而那些通过重载的create()方法创建的MediaPlayer对象却不是处于Idle状态。事实上,如果成功调用了重载的create()方法,这些对象就已经是Prepare状态了。
   
    2. 一般情况下,由于种种原因一些播放控制操作可能会失败,如不支持的音频/视频格式、缺少隔行扫描的音频/视频、分辨率太高、流超时等,因此,错误报告和恢复在这种情况下是非常重要的。有时由于编程错误,在处于无效状态的情况下调用了一个播放器控制操作的情况是可能发生的。在所有这些错误条件下,内部播放引擎会调用一个由客户端程序提供的OnErrorListener.onError()方法。客户端程序可以通过调用 setOnErrorListener(android.media.MediaPlayer.OnErrorListener)方法注册OnErrorListener对象。
一旦发生错误,MediaPlayer对象会进入Error状态。为了重用一个处于Error状态的MediaPlayer对象,可以调用reset()方法把这个对象恢复到Idle状态。注册一个OnErrorListener来获知内部播放引擎发生的错误是一个好的编程习惯。在不合法的状态下调用一些方法,如prepare()、prepareAsync()和setDataSource()等会抛出ILlegalStateException异常。

    3. 调用 setDataSource(FileDescriptor), setDataSource(String), setDataSource(Context, Uri), setDataSource(FileDescriptor, long, long)方法会使处于Idle状态的对象迁移到Initialized状态。若当此MediaPlayer对象处于其他状态下,调用setDataSource()方法会抛出 ILlegalStateException异常。时刻注意调用setDataSource()方法可能会抛出的ILlegalStateException异常和IOException异常是一个好的编程习惯。

    4. 在开始播放前,MediaPlayer对象必须要进入Prepared状态。有两种方法可以使MediaPlayer对象进入Prepared状态。
        (1)、调用prepare()方法(同步):此方法返回就表示该MediaPlayer对象已经进入了Prepared状态。
        (2)、调用prepareAsync方法(异步):此方法会使MediaPlayer对象进入Preparing状态并返回,内部的播放引擎会继续未完成的工作。
当同步版本返回或异步版本的准备工作完全完成时就会调用客户端程序提供的OnPrepareListener.onPrepared()监听方法。可以调用方法MediaPlayer.setOnPreparedListener(android.media.MediaPlayer.OnPreparedListener)来注册OnPreparedListener。
Preparing是一个中间状态,如果在此状态下调用任何影响播放功能的方法,最终的运行结果都是未知的。在不合适的状态下调用prepare()和prepareAsync()方法会抛出ILlegalStateException异常。当MediaPlayer对象处于Prepared状态时,可以调整音视频的属性,如音量、播放时是否一致亮屏、循环播放等。

    5. 在要开始播放时必须调用start()方法。当此方法成功返回时,MediaPlayer对象处于Started状态。isPlaying()方法可以被用来测试某个MediaPlayer对象是否处于Started状态。
当处于Started状态时,内部播放引擎会调用客户端程序提供的OnBufferingUpdateListener.onBufferingUpdate()回调方法,此回调方法允许应用程序追踪流播放的缓冲状态。对一个已经处于Started状态的MediaPlayer对象调用start()方法没有影响。

    6. 播放可以被暂停、停止,以及调整播放进度。当调用pause()方法并返回时,会使MediaPlayer对象进入Paused状态。注意Started与Paused状态的相互转换在内部的播放引擎中是异步的,所以可能需要一点时间在isPlaying()方法中更新状态,若在播放流内容,这段时间可能会有几秒钟。
调用start()方法会让一个处于Paused状态的MediaPlayer对象从之前的暂停状态恢复到播放状态。当start()方法返回时,MediaPlayer对象的状态又会变成Started状态。对一个已经处于Paused状态的MediaPlayer对象,调用pause()方法没有任何影响。

    7. 调用stop()方法会停止播放,并且还会让一个处于Started、Paused、Prepared或者PlaybackCompleted状态的MediaPlayer对象进入Stopped状态。对一个已经处于Stopped状态的MediaPlayer对象,调用stop()方法没有影响

    8. 调用seekTo()方法可以调整播放的位置。方法seekTo(int)是异步执行的,所以可以马上返回,但是实际的定位播放操作可能需要一段时间才能完成,尤其是播放流形式的音视频。当实际的定位播放操作完成后,内部的播放引擎会调用客户端程序提供的OnSeekComplete.onSeekComplete()回调方法。可以通过setOnSeekCompleteListener(OnSeekCompleteListener)方法注册。
在此需要注意,seekTo(int)方法也可以在其他状态下调用,例如Prepared、Paused和PlaybackCompleted状态。此外,目前的播放位置,实际可以调用getCurrentPosition()方法得到,可以帮助如音乐播放器之类的应用程序不断更新播放进度。

    9. 当播放到流的末尾时,这次播放操作就彻底完成。如果调用setLooping(boolean)方法开启了循环模式,那么这个MediaPlayer对象就会重新进入到Started状态。如果没有开启循环模式,那么内部的播放引擎会调用客户端程序提供的OnCompletion.onCompletion()回调方法。可以通过调用MediaPlayer.setOnCompletionListener(OnCompletionListener)方法来设置。内部的播放引擎一旦调用了OnCompletion.onCompletion()方法,说明这个MediaPlayer对象进入了PlaybackCompleted状态。当处于PlaybackCompleted状态时,可以调用start()方法来让这个MediaPlayer对象再次进入Started状态。

MediaPlayer方法的有效状态和无效状态
方法

有效状态

无效状态

Comments

attachAuxEffect

{Initialized, Prepared, Started, Paused, Stopped, PlaybackCompleted}

{Idle, Error}

This method must be called after setDataSource. Calling it does not change the object state.

getAudioSessionId

any

{}

This method can be called in any state and calling it does not change the object state.

getCurrentPosition

{Idle, Initialized, Prepared, Started, Paused, Stopped, PlaybackCompleted}

{Error}

Successful invoke of this method in a valid state does not change the state. Calling this method in an invalid state transfers the object to the Error state.

getDuration

{Prepared, Started, Paused, Stopped, PlaybackCompleted}

{Idle, Initialized, Error}

Successful invoke of this method in a valid state does not change the state. Calling this method in an invalid state transfers the object to the Error state.

getVideoHeight

{Idle, Initialized, Prepared, Started, Paused, Stopped, PlaybackCompleted}

{Error}

Successful invoke of this method in a valid state does not change the state. Calling this method in an invalid state transfers the object to the Error state.

getVideoWidth

{Idle, Initialized, Prepared, Started, Paused, Stopped, PlaybackCompleted}

{Error}

Successful invoke of this method in a valid state does not change the state. Calling this method in an invalid state transfers the object to the Error state.

isPlaying

{Idle, Initialized, Prepared, Started, Paused, Stopped, PlaybackCompleted}

{Error}

Successful invoke of this method in a valid state does not change the state. Calling this method in an invalid state transfers the object to the Error state.

pause

{Started, Paused, PlaybackCompleted}

{Idle, Initialized, Prepared, Stopped, Error}

Successful invoke of this method in a valid state transfers the object to the Paused state. Calling this method in an invalid state transfers the object to the Error state.

prepare

{Initialized, Stopped}

{Idle, Prepared, Started, Paused, PlaybackCompleted, Error}

Successful invoke of this method in a valid state transfers the object to the Preparedstate. Calling this method in an invalid state throws an IllegalStateException.

prepareAsync

{Initialized, Stopped}

{Idle, Prepared, Started, Paused, PlaybackCompleted, Error}

Successful invoke of this method in a valid state transfers the object to the Preparingstate. Calling this method in an invalid state throws an IllegalStateException.

release

any

{}

After release(), the object is no longer available.

reset

{Idle, Initialized, Prepared, Started, Paused, Stopped, PlaybackCompleted, Error}

{}

After reset(), the object is like being just created.

seekTo

{Prepared, Started, Paused, PlaybackCompleted}

{Idle, Initialized, Stopped, Error}

Successful invoke of this method in a valid state does not change the state. Calling this method in an invalid state transfers the object to the Error state.

setAudioAttributes

{Idle, Initialized, Stopped, Prepared, Started, Paused, PlaybackCompleted}

{Error}

Successful invoke of this method does not change the state. In order for the target audio attributes type to become effective, this method must be called before prepare() or prepareAsync().

setAudioSessionId

{Idle}

{Initialized, Prepared, Started, Paused, Stopped, PlaybackCompleted, Error}

This method must be called in idle state as the audio session ID must be known before calling setDataSource. Calling it does not change the object state.

setAudioStreamType

{Idle, Initialized, Stopped, Prepared, Started, Paused, PlaybackCompleted}

{Error}

Successful invoke of this method does not change the state. In order for the target audio stream type to become effective, this method must be called before prepare() or prepareAsync().

setAuxEffectSendLevel

any

{}

Calling this method does not change the object state.

setDataSource

{Idle}

{Initialized, Prepared, Started, Paused, Stopped, PlaybackCompleted, Error}

Successful invoke of this method in a valid state transfers the object to the Initializedstate. Calling this method in an invalid state throws an IllegalStateException.

setDisplay

any

{}

This method can be called in any state and calling it does not change the object state.

setSurface

any

{}

This method can be called in any state and calling it does not change the object state.

setVideoScalingMode

{Initialized, Prepared, Started, Paused, Stopped, PlaybackCompleted}

{Idle, Error}

Successful invoke of this method does not change the state.

setLooping

{Idle, Initialized, Stopped, Prepared, Started, Paused, PlaybackCompleted}

{Error}

Successful invoke of this method in a valid state does not change the state. Calling this method in an invalid state transfers the object to the Error state.

isLooping

any

{}

This method can be called in any state and calling it does not change the object state.

setOnBufferingUpdateListener

any

{}

This method can be called in any state and calling it does not change the object state.

setOnCompletionListener

any

{}

This method can be called in any state and calling it does not change the object state.

setOnErrorListener

any

{}

This method can be called in any state and calling it does not change the object state.

setOnPreparedListener

any

{}

This method can be called in any state and calling it does not change the object state.

setOnSeekCompleteListener

any

{}

This method can be called in any state and calling it does not change the object state.

setScreenOnWhilePlaying any

{}

This method can be called in any state and calling it does not change the object state.

setVolume

{Idle, Initialized, Stopped, Prepared, Started, Paused, PlaybackCompleted}

{Error}

Successful invoke of this method does not change the state.
setWakeMode

any

{}

This method can be called in any state and calling it does not change the object state.

start

{Prepared, Started, Paused, PlaybackCompleted}

{Idle, Initialized, Stopped, Error}

Successful invoke of this method in a valid state transfers the object to the Started state. Calling this method in an invalid state transfers the object to the Error state.

stop

{Prepared, Started, Stopped, Paused, PlaybackCompleted}

{Idle, Initialized, Error}

Successful invoke of this method in a valid state transfers the object to the Stopped state. Calling this method in an invalid state transfers the object to the Error state.

getTrackInfo

{Prepared, Started, Stopped, Paused, PlaybackCompleted}

{Idle, Initialized, Error}

Successful invoke of this method does not change the state.

addTimedTextSource

{Prepared, Started, Stopped, Paused, PlaybackCompleted}

{Idle, Initialized, Error}

Successful invoke of this method does not change the state.

selectTrack

{Prepared, Started, Stopped, Paused, PlaybackCompleted}

{Idle, Initialized, Error}

Successful invoke of this method does not change the state.

deselectTrack

{Prepared, Started, Stopped, Paused, PlaybackCompleted}

{Idle, Initialized, Error}

Successful invoke of this method does not change the state.

MediaPlayer中可使用的回调

在播放过程中,应用程序也许会想去注册一些回调函数来获取一些内部状态更新或运行错误的事件信息。所有这些都可以通过正确的设置一些监听对象来实现:

setOnPreparedListener(OnPreparedListener)setOnPreparedListener, 

setOnVideoSizeChangedListener(OnVideoSizeChangedListener)setOnVideoSizeChangedListener,

setOnSeekCompleteListener(OnSeekCompleteListener)setOnSeekCompleteListener, 

setOnCompletionListener(OnCompletionListener)setOnCompletionListener, 

setOnBufferingUpdateListener(OnBufferingUpdateListener)setOnBufferingUpdateListener, 

setOnInfoListener(OnInfoListener)setOnInfoListener, 

setOnErrorListener(OnErrorListener)setOnErrorListener, etc

为了能通过这些监听器正确收到相关联的回调,在创建MediaPlayer对象时,要确保它所在的线程必须有自己的消息循环(Looper)。


MediaPlayer中的内嵌类
interface MediaPlayer.OnBufferingUpdateListener Interface definition of a callback to be invoked indicating buffering status of a media resource being streamed over the network. 
interface MediaPlayer.OnCompletionListener Interface definition for a callback to be invoked when playback of a media source has completed. 
interface MediaPlayer.OnErrorListener Interface definition of a callback to be invoked when there has been an error during an asynchronous operation (other errors will throw exceptions at method call time).  
interface MediaPlayer.OnInfoListener Interface definition of a callback to be invoked to communicate some info and/or warning about the media or its playback. 
interface MediaPlayer.OnPreparedListener Interface definition for a callback to be invoked when the media source is ready for playback. 
interface MediaPlayer.OnSeekCompleteListener Interface definition of a callback to be invoked indicating the completion of a seek operation. 
interface MediaPlayer.OnTimedTextListener Interface definition of a callback to be invoked when a timed text is available for display. 
interface MediaPlayer.OnVideoSizeChangedListener Interface definition of a callback to be invoked when the video size is first known or updated  
class MediaPlayer.TrackInfo Class for MediaPlayer to return each audio/video/subtitle track's metadata. 
                      


PS:以上所有内容都可以到MediaPlayer Android官方文档获取更准确的介绍。



Android多媒体功能开发(6)——使用MediaPlayer类播放音频 使用MediaPlayer播放音频的基本流程是创建MediaPlayer对象、设置音频数据源、准备、开始播放、停止播放、释放资源。播放过程中可以暂停和继续,停止播放后可以重新准备再次播放,也可以重置音频数据源再播放其他音频。 阅读详情

相关推荐

Android中的MediaPlayer的使用详解

今天本文介绍的是Andriod系统自带的Mediaplayer,和VideoView实现简单的音乐和视频的播放,至于想做出如酷狗音乐这样的APP的话,只要想做,应该也不难,都是基于此实现了功能的扩展。 Android的MediaPlayer包含了Audio和Video的播放功能,在Android的界面上,Music和Video两个应用程序都是调用MediaPlayer来实现的。 一、播放音频文件 首先看看MediaPlaer的生命周期 下面是MediaPlayer提供的常用方法 方法

Jason_Julie的博客 2万+

56. 【Android教程】媒体播放器:MediaPlayer

Android 系统提供了几种播放音频和视频的方式,其中最常用的就是 MediaPlayer,和其他功能组件一样都有很多第三方框架提供更加丰富完备的功能,但是基本用法和时序基本都是参照 MediaPlayer 来设计的,本节就来看看 MediaPlayer 的使用方法。

这是一个web全栈开发的博客,取其精华去其糟粕,争取让大家一看就懂,一学就会,一用就成~ 8036

Android平台通过C++的MediaPlayer进行多媒体播放在调用prepare时死锁问题

先来看下下面的测试代码: mptest.cpp #include #include #include #include #include #include #include #include #include #include #include "utils/Log.h" #include #include #include #include #include

I2Cbus的专栏 4498

Android MediaPlayer类

1. MediaPlayer方法 MediaPlayer创建 可以直接调用构造函数,利用setDataSource()方法设置资源。 MediaPlayer mp = new MediaPlayer(); // path可以是本地路径,也可以是网络地址 mp.setDataSource(String path); 也可以调用create()方法,create()方法会直接调用pr...

假装你是大灰狼的专栏 1万+

Android MediaPlayer详解(一)

Android MediaPlayer 使用详解 MediaPlayer生命周期 MediaPlayer 1.获取MediaPlayer实例:     直接new的方式或者使用create的方式:     MediaPlayer mp = new MediaPlayer(); MediaPlayer mp = MediaPlayer.create(this, R

Android开发-CXY的博客 2503

【Android笔记60】Android之多媒体播放SurfaceView和SurfaceHolder介绍

Surface是一个位于【android.view】包下的类,该类用于保存多媒体的原始缓冲区数据,从这个类中的注释内容可以知道。处理由屏幕合成器管理的原始缓冲区。Surface通常由图像缓冲区(如SurfaceTexture、android.media.MediaRecorder或android.renderscript.Allocation)的使用者创建或从其创建,并交给某种生产者(如OpenGL、MediaPlayer或CameraDevice)进行绘制。

✅ Java 开发工程师 1115

安卓多媒体API——多媒体播放MediaPlayer

序 在画布与绘制的部分就已经学习了如何实现简易的视频播放、暂停、停止 https://blog.youkuaiyun.com/nishigesb123/article/details/89468251#t7 而这部分关于安卓中的多媒体播放,利用这部分知识,可以实现一个“真正”的媒体播放器。 媒体播放概述 Android的多媒体框架包括支持播放多种常见的媒体类型,使您可以轻松地把音频、视频和图像集成到...

旧日灯塔 2083

Android MediaPlayer实例详解与实战

Android MediaPlayer类是Android系统中用于播放音频和视频的核心组件之一,封装了底层多媒体解码与渲染的复杂逻辑,提供了简洁易用的API接口。它支持多种媒体格式,并能处理本地文件、网络流等多种数据源,广泛应用于音乐播放器、视频播放器、在线流媒体等场景。MediaPlayer在整个Android多媒体框架中占据核心地位,与AudioManager、SurfaceView等组件协同工作,实现完整的播放流程。理解其基本功能与生命周期,是掌握Android多媒体开发的关键第一步。

weixin_42629522的博客 948

Android车载应用开发——音视频基础知识与MediaPlayer

多媒体应用是车载信息娱乐系统的一个重要组成部分,一般包含音视频播放、收音机、相册等。

Dream It Possible 1439

深入解析Android MediaPlayer源码与实践

Android作为一个强大的移动操作系统,其在多媒体处理方面的表现尤为突出,提供了丰富的API支持多媒体的播放和录制。本章我们将从基础层面探讨Android多媒体播放的概念,为后续深入分析MediaPlayer类以及更高级的多媒体应用打下坚实的基础。MediaPlayer类提供了对媒体文件播放的全方位控制能力。这包括但不限于开始播放、暂停、停止、继续播放和调整音量等。这些功能是通过MediaPlayer类提供的方法来实现的,具体包括:start(): 开始播放媒体,若媒体尚未准备好,则会抛出异常。

weixin_30476025的博客 1174

银河麒麟V10离线安装VLC播放器:依赖处理与3.0.9.2版本实操指南

在国产化操作系统日益普及的背景下,软件安装方式成为政企内网用户关注的重点。离线安装作为一种不依赖公网源的部署手段,常用于解决内网环境下的软件获取问题。其核心在于理解Linux包管理机制,如dpkg与apt对依赖关系的处理逻辑。掌握这一原理,不仅能应对多媒体软件的部署,也能提升系统维护效率。VLC作为跨平台多媒体播放器,凭借强大的解码能力与协议支持,广泛应用于本地视频播放、RTSP拉流及监控大屏等场景。本文从离线安装的通用概念出发,结合银河麒麟V10桌面版的实际环境,详细梳理了VLC 3.0.9.2离线包的获

weixin_32247165的博客 369

Android详细教程(基础篇):三十、Android 多媒体播放MediaPlayer详解

简介 可以使用MediaPlayer类播放Mp3以及视频。 public class MediaPlayer extendsObject java.lang.Object ↳ android.media.MediaPlayer 本部分...

二总的猫 1242

MySQL8.2.0下载安装

4、点击No thanks,just start my download,就是只是开始下载的意思,点击下载,等待下载完成。5、新建空白行,或直接双击紧挨的空白行,把复制的mysql的安装路径bin路径复制粘贴过来,确定,确定,确定。1、上面点击finish后,自动勾选了run mysql配置,自动会打开配置页面,点击Next。1、双击安装包,进入安装流程,勾选我同意 I accept,next。2、根据自己需要选择,我选的第二个,可以自己改安装路径。2、默认,点击Next,记住默认端口3306。

m0_59681797的博客 1万+

Android学习——多媒体播放

多媒体播放——MediaPlayer 简介 Android的多媒体框架包栝支持播放多种常见的媒体类型,使您可以轻松地把音频、视频和图像集成到你的应用。你可以播放音频或视频媒体文件,这些文件是存储在你的应用程序的资源文件中的。应用程序的资源文件可以是文件系统中独立的文件,或通过网络连接获取的-一个数据流,所有使用MediaPlayer APIS的资源文件。 **注意:**你只能在标准输出设备上檑放音...

UUUUUltraman的博客 858

从零开始:用YOLOv8-Pose实现实时人体姿态检测(附完整代码)

本文提供了一份从零开始的完整实战指南,详细介绍了如何使用YOLOv8-Pose构建实时人体姿态检测系统。内容涵盖环境搭建、数据准备、模型训练与调优,以及高性能部署和进阶应用开发,并附有可直接运行的代码示例,帮助开发者快速掌握Pose Estimation技术并将其应用于实际项目。

h6i7j8的博客 621

Adams与Matlab联合仿真入门:从零搭建你的第一个动力学模型

本文为Adams与Matlab联合仿真新手提供了一份详尽的入门指南。文章从软件环境配置、版本兼容性检查讲起,逐步演示了如何在Adams中构建单摆动力学模型并定义输入输出接口,以及在Matlab/Simulink中搭建控制回路。通过一个完整的受控单摆实例,手把手教你完成从模型导出、模块生成到执行联合仿真的全流程,帮助你快速搭建并运行第一个联合仿真模型,实现动力学与控制系统的协同验证。

g5h6i7j的博客 699

Android -- 多媒体播放之MediaPlayer使用内部实现简析

Android -- MediaPlayer内部实现简析 在之前的博客中,已经介绍了使用MediaPlayer时要注意的内容。如今,这里就通过一个MediaPlayer代码实例,来进一步分析MediaPlayer内部是怎样运作、实现的;当然这里的分析仅仅截止究竟层调用播放器之前...

aoe41606的博客 970

Ubuntu环境下读取罗技G29方向盘信息

Ubuntu环境下读取罗技G29方向盘信息

工大机器人工作室 3463

android mediaplayer api 详解,[android] 多媒体播放api简介详解

packagecom.tsh.tshplayer;importjava.io.File;importjava.io.IOException;importandroid.app.Activity;importandroid.content.SharedPreferences.Editor;importandroid.media.AudioManager;importandroid.media.Med...

weixin_35716518的博客 483

基于Matlab-Simulink的大林算法控制系统设计与振铃消除实验

本文详细介绍了基于Matlab-Simulink的大林算法控制系统设计与振铃消除实验。通过分析纯滞后系统的控制难题,探讨大林算法在工业控制中的应用优势,并提供Matlab-Simulink环境搭建、控制器D(z)设计、振铃消除及仿真实验的完整流程。文章还对比了大林算法与PID控制的性能差异,为工程实践提供参考。

dropout6artist的博客 796

SDR 和 DDR 的区别

SDR 和 DDR 的差别,最明显提现在传输速率和频率上。DDR SDRAM与SDRAM的基本结构是相似的,最根本的区别在于DDR 支持在一个时钟周期内传输两次数据,,SDR 只能传输一次数据。

串起点滴 1960

Android MediaPlayer

这里写自定义目录标题参考网址 参考网址 1、https://blog.youkuaiyun.com/wangmx1993328/article/details/82798626

zksdu的专栏 1371

INCA ProF文件解析

本博文从实际应用出发,介绍INCA prof文件的关键信息,通过实例,描述当得到一个刷写需求后,如何在不改变用户之前的使用习惯的前提下,满足原有的INCA刷写应用数据和标定程序的需求。 声明:本文不涉及项目名称,没有商业目的,纯属分享技术,乐享知识。

汽车电子软件领域知识分享 1万+

Android MediaPlayer 设置音轨

因为很多视频流是包含多个音轨的,所以实现播放器的时候,需要考虑音轨选择的问题。 在android中,音频、视频统一被类TrackInfo描述,当然还不止这两类,可以看一下定义,还包含字幕等类型,都为Track信息。         public static final int MEDIA_TRACK_TYPE_UNKNOWN = 0;         public static final

jl2011的博客 1万+

大华录相机NVR1104HS/NVR1108HS 最新升级包

大华录相机NVR1104HS/NVR1108HS 最新升级包

xpay最新版V3.1,XPay 个人收款支付系统 完全免费 资金直接到达本人账号 无需签约(java版)

xpay最新版V3.1,XPay 个人收款支付系统 完全免费 资金直接到达本人账号 无需签约(java版)

Android MediaPlayer的核心原理

本 文主要介绍的是Android中很重要也最为复杂的媒体播放器(MediaPlayer)部分的架构。对于Android这样一个完整又相对复杂的系统, 一个MediaPlayer功能的实现不在其具体的功能,而是具体功能如何适应Android系统Android MediaPlayer的主要具体实现在OpenCore的Player中,这部分不是本文的关注点。本文关注的是MediaPlayer系统的架构,

moruihong的专栏 3174

行业资料-建筑装置-带预分解炉的活性石灰煅烧系统及方法.zip

行业资料-建筑装置-带预分解炉的活性石灰煅烧系统及方法.zip

Android Simple MediaPlayer 教程

Android Simple MediaPlayer 教程 项目介绍 Android Simple MediaPlayer 是一个基于 Google 的示例项目(尽管链接指向的是 googlearchive 表明项目可能已迁移或归档),它展示了如何在 Android 应用中简单地使用 MediaPlayer 类来播放音频文件。本项目旨在提供给开发者一个入门级的范例,说明如何从应用的资源中加载并播放...

gitblog_00524的博客 921

(67页PPT)智能制造行业RPA常见场景解决方案.pptx

(67页PPT)智能制造行业RPA常见场景解决方案.pptx

上一篇: Android -- Init进程对属性系统的处理流程分析
下一篇: Android -- 源码平台下JAR包的引入与编译
第一序列丶
博客等级 码龄11年 249粉丝 77原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值