Android MediaPlayer(1)

来源:互联网 发布:华为s2700绑定mac地址 编辑:程序博客网 时间:2024/06/06 05:29

audiofling audiotrack

audiotrack


---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

播放流程和声音通路


---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

android MediaPlayer 声音播放流程和声音通路

       在android原生的媒体播放器中是由mediaplayerservice来控制媒体播放器的,在mediaplayerservice中创建了mediaplayer,在mediaplayer.java的native方法通过jni调用android_media_mediaplayer.cpp中的方法,接着往下调用mediaplayer.cpp中的方法,mediaplayer通过ipc机制调用mediaplayerService中的方法,mediaplayerService通过对文件格式的判断来选择不同的播放器来播放音乐,当是midi格式时会选择sonivox来播放,当系统的配置文件中允许ogg格式由vorbris来播放时则用vorbris,否则用stagefright来播放。其余的格式由配置文件选择是否由stagefright来播放,是则由stagefright播放,不是则由opencore的pvplayer来播放。
      stagefright由awesongplayer来控制,他会调用setDatasource()方法来加载音频文件,根据音频文件的头字段不同来选择不同的解析器,这个解析器会进行av分离分离出audioTrack和videoTrack,接着会根据audioTrack的mineType类型来选择不同的编码器来进行编码,这个是由audioSource来进行解码,audioSource是对omxCodec的封装,而audioPlayer则是用来控制audioSource和audioTrack的。audioplayer调用fillBuffer()方法将解完码的数据写进data中最终将解完码的数据流最后会传给AudioTrack,由audioTrack来交给audioFlinger,audioTrack通过调用creataudioTrack()来得到audioFlinger返回的iaudioTrack,将数据流写进iaudioTrack的共享buffer中,然后audioFlinger读出缓存中的数据交给playbackTread进行混音或者直接输出给缓存并最终将数据给audioOutputStream。

 ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Developer Guides

For more information about how to use MediaPlayer, read the  Media Playback developer guide.

State Diagram

Playback control of audio/video files and streams is managed as a state machine. The following diagram shows the life cycle and the states of a MediaPlayer object driven by the supported playback control operations. The ovals represent the states a MediaPlayer object may reside in. The arcs represent the playback control operations that drive the object state transition. There are two types of arcs. The arcs with a single arrow head represent synchronous method calls, while those with a double arrow head represent asynchronous method calls.

MediaPlayer State diagram

 http://developer.android.com/reference/android/media/MediaPlayer.html

Using MediaPlayer


One of the most important components of the media framework is the MediaPlayer class. An object of this class can fetch, decode, and play both audio and video with minimal setup. It supports several different media sources such as:

  • Local resources
  • Internal URIs, such as one you might obtain from a Content Resolver
  • External URLs (streaming)

For a list of media formats that Android supports, see the Android Supported Media Formats document.

Here is an example of how to play audio that's available as a local raw resource (saved in your application'sres/raw/ directory):

MediaPlayer mediaPlayer = MediaPlayer.create(context, R.raw.sound_file_1);mediaPlayer.start(); // no need to call prepare(); create() does that for you

In this case, a "raw" resource is a file that the system does not try to parse in any particular way. However, the content of this resource should not be raw audio. It should be a properly encoded and formatted media file in one  of the supported formats.

And here is how you might play from a URI available locally in the system (that you obtained through a Content Resolver, for instance):

Uri myUri = ....; // initialize Uri hereMediaPlayer mediaPlayer = new MediaPlayer();mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);mediaPlayer.setDataSource(getApplicationContext(), myUri);mediaPlayer.prepare();mediaPlayer.start();

Playing from a remote URL via HTTP streaming looks like this:

String url = "http://........"; // your URL hereMediaPlayer mediaPlayer = new MediaPlayer();mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);mediaPlayer.setDataSource(url);mediaPlayer.prepare(); // might take long! (for buffering, etc)mediaPlayer.start();

Note: If you're passing a URL to stream an online media file, the file must be capable of progressive download.

Caution: You must either catch or pass IllegalArgumentException andIOException when usingsetDataSource(), because the file you are referencing might not exist.

http://developer.android.com/guide/topics/media/mediaplayer.html#mediaplayer

 举例具体的播放例子:

MediaPlayer mediaPlayer = new MediaPlayer();
                    try {
                        String filePath = Environment.getRootDirectory() + SOUND_EFFECTS_PATH + SOUND_EFFECT_FILES[SOUND_EFFECT_FILES_MAP[effectType][0]];
                        mediaPlayer.setDataSource(filePath);
                        mediaPlayer.setAudioStreamType(AudioSystem.STREAM_SYSTEM);
                        mediaPlayer.prepare();
                        mediaPlayer.setVolume(volFloat, volFloat);
                        mediaPlayer.setOnCompletionListener(new OnCompletionListener() {
                            public void onCompletion(MediaPlayer mp) {
                                cleanupPlayer(mp);
                            }
                        });
                        mediaPlayer.setOnErrorListener(new OnErrorListener() {
                            public boolean onError(MediaPlayer mp, int what, int extra) {
                                cleanupPlayer(mp);
                                return true;
                            }
                        });
                        mediaPlayer.start();
                    } catch (IOException ex) {
                        Log.w(TAG, "MediaPlayer IOException: "+ex);
                    } catch (IllegalArgumentException ex) {
                        Log.w(TAG, "MediaPlayer IllegalArgumentException: "+ex);
                    } catch (IllegalStateException ex) {
                        Log.w(TAG, "MediaPlayer IllegalStateException: "+ex);
                    }

 ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

stagefright与opencore对比(转)

1引言
Android froyo版本多媒体引擎做了变动,新添加了stagefright框架,并且默认情况android选择stagefright,弃用之前的opencore,仅仅对opencore中的omx-component部分做了引用。
Stagefright自android2.0后才添加,其稳定性有待商榷,是否存在bug也未知,opencore自android诞生起便存在,稳定性有保障。不过,从目前android代码看,opencore有被stagefright取代的趋势,所以在opencore上所作工作也许会无法沿用。Opencore上的开发较stagefright上要复杂耗时些。

2框架变动
以MediaPlayer为例,我们先看一下多媒体的简单框架。
 
上图可知,stagefright是在MediaPlayerService这一层加入的,和opencore是并列的,在选用opencore还是stagefright的代码切换上也非常容易。
 具体stagefright的内部变动,可见下图概述。Stagefright并没有完全抛弃opencore,主要是做了一个OMX层,用来引用opencore的omx-component部分。而stagefright内部而言,与opencore是完全不同的设计。AudioPlayer::mSource(MediaSource),AudioPlayer::mAudioSink(MediaPlayerBase::AudioSink),AudioPlayer::mAudioTrack(AudioTrack)

类与类之间的聚合关系和组合关系:人和头是聚合关系,人和衣服是组合关系
 

3具体差异
3.1所支持的文件格式

Opencore所支持的格式。
       
Stagefright所支持的格式。


3.2 Parser和codec部分开发有差异
 Opencore与stagefright两套机制,对于我们的开发而言,主要体现在parser和codec部分。Opencore方面,必须按照其规范完成相应的parser-node,codec则要按照omx规范实现相应的component。Stagefright方面,则要按照其规范实现相应的extractor和decoder。
 最基本的实现,二者是相同的,可以共用,差别在封装上,opencore难度和工作量要大。


3.3 数据处理机制不同
Opencore处理流程如下图示。
 
 engine分别创建audio/video datapath,parser/dec/sink作为node节点由各自datapath连接起来,后续node节点由统一调度器调度。
Stagefright处理流程如下图示。
 
 Audioplayer为AwesomePlayer的成员,audioplayer通过callback来驱动数据的获取,awesomeplayer则是通过videoevent来驱动。二者有个共性,就是数据的获取都抽象成mSource->Read()来完成,且read内部把parser和dec绑在一起。
 Opencore和stagefright处理机制对比:
 (1)Opencore的parser与dec是分离的,各行其职;stagefright则是绑在一起作为一个独立的原子操作。
 (2)Stagefright通过callback和videoevent来驱动数据输出;opencore是通过sink-node节点控制输出。
 (3)Opencore中parser/dec/sink是并行处理的;stagefright中为串行处理。

3.4 AV同步
 Opencore有一个主clock,audio/video分别与该主clock同步,作为输出的判定依据,且audio会不断校准主clock。
 Stagefright部分,audio完全是callback驱动数据流,video部分在onVideoEvent里会获取audio的时间戳,是传统的AV时间戳做同步。

3.5 稳定性
 客观来讲,opencore存在时间长,相对稳定;stagefright刚推出,肯定会有未预知的bug存在。

4 总结
1.Opencore相对成熟稳定,作为框架采用,风险小;parser/codec集成相对复杂,如果android后续版本弃用opencore转用stagefright,那多媒体引擎的选择是个问题。
2.Stagefright新推出,肯定有未预知的bug,直接采用有潜在风险;parser/codec集成相对容易,架构较opencore做了极大简化,通俗易懂。
3.目前来看opencore支持的文件格式多些。
4.Opencore与stagefright在数据处理机制及AV同步上有很大差异,需要在实际板子上评估性能差异。
5.如果在android froyo版本开发多媒体相关产品,建议采用opencore框架,这样旧版本opencore上的成果可以沿用,且节省项目时间。
6.Opencore支持的文件格式较stagefright丰富。
7.如果项目研发中android出现新版本,或stagefright做了更新,仍然维持opencore不变,多媒体引擎变更问题待ipad后再议。一种选择是一直延续采用opencore,或者在适当时候(认为stagefright足够稳定)切换到stagefright。


Stagefright阅读笔记附录
两套方案对比过程中,基本上把stagefright的代码阅读过一遍,摘录如下,以图为主。
Stagefright整体框图。
 
Stagefrightplayer里awesomeplayer初始化流程
 
Awesomeplayer框图,其中涵盖主要节点元素。
 
Stagefrightrecorder部分
 
MediaPlayer框图。
 
MediaRecorder框图。
 
Libstagefright草图,涵盖了主要节点元素。
 

转:http://blogold.chinaunix.net/u2/61880/showart.php?id=2339481

http://www.cnblogs.com/huaping-audio/archive/2011/02/18/1957482.html

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

Android StagefrightPlayer

1. 对StagefrightPlayer的好奇

前面对StagefrightPlayer的创建流程已经分析清楚了,即在Android::createPlayer中根据url的type来创建不同的player. StagefrightPlayer是Android提供的,比较经典的一个Player。但个人觉得它不怎么样,还不如ffmpeg支持的codec和parser多。还有一个opencore,更是复杂无比的东东,它采用datapath的方式,类似于大家熟悉的GStreamer。不理解大家为什么会把简单的事情复杂化。

 

2. StagefrightPlayer是个什么东东?

仔细一看代码,它也是一个空壳公司,其中就一个员工给他干活,它就是AwesomePlayer *mPlayer,在创建StagefrightPlayer时,它就被创建了。StagefrighPlayer中的所有接口都是简单调用AwesomePlayer的对应接口来实现。所以它只是一个接口人,什么都不是。这个AwesomePlayer才是我们的研究重点。

 

3. AwesomePlayer有些什么东东?

它再神奇,不也就是实现AV播放吗?看看自己直接基于Driver的MyPlayer不也就1000多行代码就把TS播放玩得很爽了。但google为了其开放性,搞得一下子搞不明白。既然想跟着Android混饭吃,只好读它这一大堆没有什么文档和注释的代码了。

AVPlayer肯定具有以下模块:

1) 数据源(如TS流,MP4...)

2) Demux (音视频分离)

3) 音视频解码

4) 音频播放和视频播放

5) 音视频同步

6) 整个工作流程

AwesomePlayer就是把以上6位员工组织起来工作的老板,下面就对每一个问题进行一一分析。

下面先看看它的几位骨干员工:

 

[cpp] view plaincopyprint?
  1. // Events    
  2. sp<TimedEventQueue::Event> mVideoEvent;    
  3. sp<TimedEventQueue::Event> mStreamDoneEvent;    
  4. sp<TimedEventQueue::Event> mBufferingEvent;    
  5. sp<TimedEventQueue::Event> mCheckAudioStatusEvent;    
  6. sp<TimedEventQueue::Event> mVideoLagEvent;    
  7.     
  8. // Audio Source and Decoder    
  9. void setAudioSource(sp<MediaSource> source);    
  10. status_t initAudioDecoder();    
  11.     
  12. // Video Source and Decoder    
  13. void setVideoSource(sp<MediaSource> source);    
  14. status_t initVideoDecoder(uint32_t flags = 0);    
  15.     
  16. // Data source    
  17. sp<DataSource> mFileSource;    
  18.     
  19. // Video render    
  20. sp<MediaSource> mVideoTrack;    
  21. sp<MediaSource> mVideoSource;    
  22. sp<AwesomeRenderer> mVideoRenderer;    
  23.     
  24. // Audio render    
  25. sp<MediaSource> mAudioTrack;    
  26. sp<MediaSource> mAudioSource;    
  27. AudioPlayer *mAudioPlayer;  

http://blog.csdn.net/myarrow/article/details/7066007

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

 

原创粉丝点击