精华内容
参与话题
问答
  • 多媒体

    千次阅读 2016-07-12 23:56:22
    本章将结合Web前端的发展历程和未来的发展前景详解现在HTML5中引入的多媒体技术HTML5的多媒体支持在HTML5规范出来之前,网页对视频和音频播放的支持基本上是靠Flash插件来实现,在HTML5之后,同文字和图片一样,音频...
    本章将结合Web前端的发展历程和未来的发展前景详解现在HTML5中引入的多媒体技术

    HTML5的多媒体支持

    在HTML5规范出来之前,网页对视频和音频播放的支持基本上是靠Flash插件来实现,在HTML5之后,同文字和图片一样,音频和视频直接变成HTML一系列规范中第一等公民,首先是JavaScript接口的支持,开发者可以使用JavaScript接口来方便的控制音视频的播放,实现例如播放、停止和记录等功能,其次HTML5中多媒体与图片一样可以用其他技术来进行操作,例如使用CSS技术来修改它的样式,例如3D变形,Web开发者可以将视频同Canvas2D或者WebGL结合在一起,而Flash插件中的视频是不能做到的。在HTML5中,对于多媒体的支持大致可以包括一下几个部分:第一是HTML的元素“video”,他用于音视频的播放;第二是“audio”,它用于单纯的音频播放;第三是可以将多个声音合成处理的WebAudio技术;第四是将照相机、麦克分与视频、音频和通信结合起来使用的最新技术WebRTC(网络实时通信),这使得Web领域使用视频对话和视频网络会议成为了现实。

    视频

    HTML5视频

    在HTML5规范定义中,Web开发者可以使用“video”元素来播放视频资源,其中视频涉及到视频编码格式,目前标准中包含了三种编码格式:Ogg、MPEG4和WebM,其中Ogg使用Theora作为视频编码格式和Vorbis作为音频编码格式,MPEG4使用H.264作为视频编码格式和AAC作为音频编码格式,WebM是有Google研发的标准,使用VP8作为视频编码格式和Vorbis作为音频编码格式。HTML提供了一些属性让开发者来使用JavaScript代码检查和操作视频,HTML5在“video”和“audio”元素之间抽象了一个基类元素“media”,结合它提供的能力,大致有一下几个方面的JavaScript编程接口,首先是资源加载和信息方面的接口,开发者可以通过特定接口检查游览器支持什么格式,如Metadata和海报(Poster)等,其次是缓冲(Buffering)处理,包括缓冲区域、进度等信息,然后是播放方面的状态,包括播放、暂停、终止等。再次是搜寻(Seeking)方面的信息,包括设置当前时间、“Timeupdate”事件,以及两个状态“Seeking”和“seeked”,最后是音量方面的设置,包括获取和设置音量、静音和音量变换等事件。

    WebKit基础设施

    WebKit提供了支持多媒体规范的基础框架,如音视频元素、JavaScript接口和视频播放等,根据WebKit的一般设计思想,它主要是提供标准的实现框架,而具体的实现有各个移植类来完成,因为音视频需要平台的支持,下图显示了各个类和它们之间的关系,也包括了Chromium移动的几个基础类:
    这里写图片描述
    首先WebKit是支持规范定义的编程接口,图中左侧的HTMLMediaElement和HTMLVideoElement类是DOM树中的节点类,包括众多的DOM接口,这些接口可以被JavaScript代码访问;其次是MediaPlayer和MediaPlayerClient两个类,MediaPlayer类是一个公共标准累,被HTMLMediaElement类使用来播放音频和视频,它本身支持提供抽象接口,具体实现依赖于不同的WebKit移植,同时一些播放器中的状态信息需要通知到HTMLMediaElement类,这里使用MediaPlayerClient类来定义这些有关状态信息的接口,HTMLMediaElement类需要继承MediaPlayerClient类并接收这些状态信息,根据前面的描述,规范要求将事件派发到JavaScript代码中,而这个实现在HTMLMediaElement类完成,然后是不同移植对MediaPlayer类的实现,其中包括MediaPlayerPrivateInterface类和WebMediaPlayerClientImpl类,前者是除了Chromium移植之外使用的标准接口也是一个抽象接口,由不同移植来实现,后者是Chromium移植的实现类,因为Chromium将WebKit复制出Blink之后就将MediaPlayerPrivateInterface类直接移除了,而在MediaPlayer类中直接调用它,WebMediaPlayerClientImpl类会使用Chromium移植自己定义的WebMediaPlayer接口类来作为实际的播放器,而真正的播放器则是在Chromium项目的代码中来实现,最后同渲染有关,这里就是之前介绍的RenderObject树和RenderLayer树,图中的RenderMedia类和RenderVideo类是RenderObject的子类,用于表示Media节点和Video节点。

    Chromium视频机制
    资源获取

    由于视频资源相对其他资源而言比较大,当用户播放视频的时候需要连续性播放以获得较好的体验,但是网络可能并不是移植都稳定和告诉,所以资源的获取对用户体验很重要,需要使用缓存机制或者其他机制来预先获取视频资源。下图是Chromium中的缓存资源类,BufferedDataSource类表示资源数据,它是一个简单的数据表示类,内存包含一个较小的内存空间(32K),实际的缓冲机制由BufferedResourceLoader类完成,在Chromium的设置中,最小的缓存空间是2M内存,最大的缓存空间是20M,并没有使用磁盘来缓存视频资源:
    这里写图片描述

    基础设施

    下图是chromium中支持硬件加速机制的视频播放所需基础设施的总体架构图,基于Chromium的多进程结构:
    这里写图片描述
    根据多进程架构的设计原则,Chromium的媒体播放器的实现应该在Renderer进程,而对于资源的获取则是在Browser进程,其中WebKit基础设施需要每个移植的具体实现,因此WebKit的Chromium移植部分提供了桥接接口,并且实现则是在Chromium代码中来完成,Chromium支持媒体播放器的具体实现涉及到不同的操作系统,目前Chromium在不同操作系统上实现的媒体播放器也不一样,下图显示了Chromium的基础类:
    这里写图片描述
    上半部分是WebKit和WebKit的Chromium移植中的相关类,下半部分是Chromium中使用硬件加速机制来实现视频播放的基础设施类,从做到分开来看,左边部分是播放器的具体实现类,右边部分是支持视频在合成器中工作的相关类。
    首先看下这些类和对象的创建过程,WebMediaPlayerClientImpl类是WebKit在创建HTMLMediaElement对象之后创建MediaPlayer对象的时候有MediaPlayer对象来创建的,当视频资源开始加载时,WebKit创建一个WebMediaPlayer对象,当然就是Chromium中的具体实现类WebMediaPlayerImpl对象,同时WebMediaPlayerClientImpl类也实现了WebMediaPlayerClient类,所以WebMediaPlayerImpl在播放视频的过程中需要向该WebMediaPlayerClient类更新各种状态,这些状态信息最终会传递到HTMLMediaElement类中,最终可能成为JavaScript事件,之后WebMediaPlayerImpl对象会创建一个WebLayerImpl对象,海湖同时创建VideoLayer对象,根据合成器的设计,Chromium还有一个LayerImpl树,在同步的时候,VideoLayer对象对应的VideoLayerImpl对象会被创建,之后Chromium需要创建VideoFrameProviderClientImpl对象,该对象将合成器的Video层同视频播放器联系起来并将合成器绘制一帧的请求转给提供视频内容的VideoFrameProvider类,这实际上是调用Chromium的媒体播放器WebMediaPlayerImpl,因为它是一个VideoFrameProvider类的实现子类,然后是Chromium如何使用这些类来生成和显示每一帧,当合成器调用每一层来绘制下一帧的时候,VideoFrameProviderClientImpl::AcquireLockAndCurrentFrame()函数会被调用,然后该函数调用WebMediaPlayerImpl类的GetCurrentFrame函数返回当前一帧的数据,VideoLayerImpl类根据需要会将这一帧数据上传到GPU的纹理对象中,当绘制完这一帧之后,VideoLayerImpl调用VidelFrameProviderClientImpl::PutCurrentFrame来通知播放器这一帧已绘制完成,并释放掉相应的资源,同时,媒体播放器也可以通知合成器有一些新帧生成,需要绘制出来,它会首先调用播放器的VideoFrameProvider::DidReceiveFrame()函数,该函数用来检查当前有没有一个VideoLayerImpl对象,如果有对象存在,需要设置它的SetNeedsRedraw标记位,这样合成器就知道需要重新生成新的一帧,最后是有关视频播放对象的销毁过程,有多种情况使Chromium需要销毁媒体播放器和相关的资源,如“video”元素被移除或者设置为隐藏等,这样视频元素对应的各种层对象以及WebKit和Chromium中的这些设施都会被销毁,WebMediaPalyerImpl类是多媒体播放器的具体实现类,在Chromium项目中,随着对Android系统的支持,Chromium既能支持左面系统也能支持移动系统,而这两者对视频和音频的支持很不一样,所以在不同系统上WebMediaPlayerImpl是如何实现和工作的也很不一样。

    桌面系统

    在桌面系统中,Chroimum使用了一套多媒体播放框架,而不是直接使用系统或者第三方库的完整解决方案,下图是Chromium在桌面系统上采用的多媒体播放引擎的工作模块和过程,这一框架称为多媒体管线化引擎,图中主要的模块四号多路分配器、音视频解码器、音视频渲染器,这些部分主要被WebMediaPlayerImpl类调用:
    这里写图片描述
    在处理音视频的管线化过程中,需要解码器和渲染其来分别处理视频和音频数据,它们均采用一种叫做“拉”而不是“推”的方式进行,也就是说有视频或者音频渲染器根据声卡或者时钟控制器,按需求来请求解码器解码数据,然后解码器和渲染器又向前请求“拉”数据,直到请求从视频资源文件读入数据,根据之前的多进程架构和Chromium的安全机制,整个管线化引擎虽然在Render进程中,但是由于Render进程不能访问声卡,所以渲染器需要通过IPC将数据或者消息同Browser进程通信,由Browser进程来访问声卡。虽然FFmpeg多媒体库拥有上述管线化的能力,但Chromium并不是将其作为一个黑盒来使用,而是分别使用FFmpeg的不同模块来实现自己的管线化引擎,目的是由自身来控制这一整个过程。Chromum使用并行FFmpeg解码技术,也就是说FFmpeg能够在帧这个层面上并行解码,当然不是针对所有格式的视频文件,目前主要针对H.264这个格式的视频。

    Android系统

    Chromium使用的是Android系统所提供的android.media.MediaPlayer类,也就是使用系统提供的音视频的渲染框架,在减少了管线化引擎带来复杂性的同时,也引入了一些额外的复杂问题。Android中的Chromium彻底抛弃了FFmpeg,直接使用系统自带的多媒体功能,因而,Android系统支持什么样的音视频格式,Chromium就只能支持什么样的相应格式,同时由于Android多媒体框架的优点使得视频元素仍然能够同HTML5中的其他技术一起工作。
    Ⅰ Android媒体播放框架
    Android中使用一个名为“MediaService”的服务进程来为应用程序提供音频和视频的播放功能,对于每一个使用多媒体播发功能的应用程序来说,“MediaService”服务是透明的,因为Android系统提供了“MediaService”的封装接口,这些接口隐藏了“MediaService”服务内部的细节,应用程序只是使用了简单的播放接口。MediaService能够为多个播放器提供服务,对于播放器来说,它的主要设置为两个参数,其一是输入的URL,第二是输出结果的绘制目标,下图描述了Android的播放器类和相关类:
    这里写图片描述
    当应用程序使用播放器的时候,Chromium可以创建MediaPlayer类的对象,调用setDataSource函数来设置待播放视频文件,并调用setSurface来设置视频结果绘制的目标-SurfaceTexture对象,这是一个GL的纹理对象,实际的解码和绘制是在MediaService进程中完成,这需要该纹理对象能够被多个不同的GL上下文对象所访问,支持多个GL上下文对象访问的GL纹理对象的类型GL_TEXTURE_EXTERNAL_OES,由此可以看到Chromium使用Android系统提供的音视频播放功能,表示Chromium使用Android系统的音视频解码器,所以Chromium是依赖与Android系统支持的音视频编码格式,而不像Chromium桌面版独立与操作系统的音视频编码格式。
    Ⅱ Chromium的视频解决方案
    在Android系统上,因为Chromium使用系统的多媒体框架,所以没有自己的管线化引擎,主要的工作是将Chromium的架构同Android多媒体框架结合起来以完成对网页中视频和音频的播放。下图是Chromium的Android系统上支持音频和视频播放的播放器主要类,因为Chromium的多进程架构,所以这里面包括两大部分,首先是右侧的Render进程的相关类,根据前面Chromium的桌面版上支持多媒体的相关类,可以看到WebKit::WebMediaPlayer类和WebMediaPlayerClient类来自于WebKit的Chromium移植,这两个类在所有平台上的定义都是一样的:
    这里写图片描述
    上图中右侧的Render进程,从上向下首先是WebMediaPlayerAndroid类,它同之前的WebMediaPlayerImpl类相似,表示的是Android系统上网页中的播放器,同video元素是一一对应的,与桌面系统不一样的是,Android系统使用RendeerMediaPlayerManager类来管理所有的WebMediaPlayerAndroid对象,因为一个网页中可能包含多个播放器实例,而WebMediaPlayerProxyAndroid则是同Browser进程来通信的,因为真正的Android播放器是在Browser进程中,主要请求Browser进程创建实际的Android的MediaPlayer类并设置播放文件的信息,左侧则是实际的播放器,在JNI(Java Native Interface)之上的是Java类,该播放器就是使用Android系统的android.media.MediaPlayer及其相关类来工作的,从下向上看首先是BrowserMediaPlayerManager类,该类不仅负责同Render进程的播放器类进行通信,而且自身又是一个播放器的管理类,它包含当前全部网页中的所有播放器对象,因为可能会有多个Render进程,所以只能通过播放器的唯一标记来区分这些播放器,BrowserMediaPlayerManager类管理称为MediaPlayerAndroid类的多个对象,而MediaPlayerAndroid的子类MediaPlayerBridge则是具体实现类,该子类能够与Java层中相同名字类通过JNI调用来控制Android系统的播放器类,以上的基本过程就是如何在网页中创建一个播放器,从右向左直到android.media.MediaPlayer对象被创建,同时Chromium获取网页中设置的视频文件的URL字符串然后传递并设置该URL字符串到Android的媒体播放器作为输入,对于输出Chrome使用SurfaceTexture对象作为输出目标,当Chromium调用WebMediaPlayerAndroid类的play函数时,该函数发起请求从Render进程到Browser进程来创建输出目标,也就是SurfeceTexture对象,下图描述了这个过程中使用到的主要类和之间的关系:
    这里写图片描述
    右侧的Render进程,最上面的StreamTexureFactoryImpl是创建目标结果存储空间的类,它被WebMediaPlayerAndroid类使用来创建所需要的结果存储对象StreamTexture,由于实际的对象是在Browser进程中创建的,所以Render进程中的StreamTextureProxy类就是一个代理类,最后的请求是通过GPUChannelHost类传递给Browser进程。在Browser进程中,负责处理上述请求的是GPU线程,该线程有StreamTextureManagerAndroid类处理所有创建StreamTexture对象的请求,StreamTexture对象的直接使用者是GPU线程,Render进程需要区分和标识这些StreamTexture对象,具体的方法是使用整形标记符来表示Browser进程中的各个StreamTexture对象,StreamTexture和StreamTextureManager是基础抽象类,在Android系统上,StreamTextureAndroid和StreamTextureManagerAndroid是实际的实现类,StreamTextureAndroid表示的是C++端的桥接类,它包含一个SurfaceTexture对象,该对象会在Java端创建一个android.graphics.SurfaceTexture对象,Chromium设置该对象到MediaPlayer对象作为播放器的输出目标,当视频播放器将解码后的结果写入到SurfaceTexture中后,播放器需要告诉Chromium游览器这一信息,Chroimum游览器需要执行合成操作而合成器在Render进程中,同之前创建SurfaceTexture对象的调用过程正好相反,这里需要使用回调机制,这就是Java层SurfaceTextureListener类的作用,该回调类注册Java层的回调对象到创建好的SurfaceTexture对象,当该对象被写入新的帧的时候,Chromium首先从Browse进程中的Java层将这一回调动作通过JNI到C++层的SurfaceTextureListener类的FrameAvailable函数,该函数经过StreamTextureAndroid和StreamTextureManagerAndroid类最后发送到Render进程,Render进程的调用过程如下:
    这里写图片描述
    网页中的视频播放有两种模式,其一是嵌入式模式,其二是全屏模式,这两种模式在解码后结果的处理上是不一样的,下图描述了全屏模式创建视频结果的绘制目标的相关类和过程:
    这里写图片描述
    当播放器进入全屏模式的时候,Chromium使用ContentVideoView类来管理,该类会创建一个SurfaceView对象并将对象传递给C++端的ContentVideoView类,因为统一时刻只有一个播放器是全屏模式,而且BrowserMediaPlayerManager管理所有的MediaPlayer对象,该管理类能够知道哪个对象是全屏模式,并将该SurfaceView对象设置到相应的MediaPlayer对象中去。

    字幕

    视频需要字母的支持,W3C组织已经开始定义支持字幕的“trace”元素,而字幕文件采用的格式是WebVTT格式,该格式看起来比较直观,简单的例子就是时间戳区间加上相应的字母文字,一下是使用字母的视频元素,因为语言的问题,每个“video”元素可以有多个“trace”元素,每个“trace”元素可以用来表示一个语言:

    <video controls="controls">
      <source src="video.mp4" type="video/mp4">
      <trace src="trace.vtt" kind="subtitles" srclang="en" label="English"></trace>
    </video>

    字幕文件的解释工作不依赖与各个WebKit移植,WebCore模块支持“track”元素解析、字幕文件解析等功能,下图是WebKit支持字幕功能的主要类:
    这里写图片描述
    “track”本身是一个HTML元素,因此它在DOM中有相应的节点元素,这就是HTMLTrackElement类,根据规范,“track“元素有一个重要的属性”src“,该属性指定了字幕文件的URL,WebKit使用LoadableTextTrack类来负责解析字幕文件并使用TextTrack类来存储解析后的结果,目前WebKit只支持WebVTT格式的字幕,使用WebVTTParser解析器来解释它们。
    下面一部分是提供接口,这里的接口是WebKit的Chromium移植所定义的接口不同额移植所定义的接口可能不一样,接口有两个类,WebInbandTextTrack和WebInbandTextTrackClient类,且是公开接口,WebInbandTextTrack类是有Chromium实现由WebKit调用,而WebInbandTextTrackClient则是有WebKit实现,实现类就是InbandTextTrackPrivateImpl,它实现WebInbandTextTrackClient的接口,然后后调用解析后的字幕并返回给Chromium。上述需要将一些消息传递给JavaScript代码,因为规范提供了JavaScript接口,开发者可以让JavaScript代码控制或者获取字幕信息,下面是Chromium中支持框架,下图描述了Chromium是如何将WebKit中的字幕信息桥接到多媒体管线化引擎中的:
    这里写图片描述
    在Chromium中,WebMediaPlayerImpl类创建继承类的对象,并设置WebInbandTextTrackClient对戏那个到该对象,该对象实际上是InTextTrack,它包含解析后的字幕内容,这样TextTrackImpl就可以获取字幕的内容,而TextTrack对象会被多媒体的管线化引擎多调用并渲染在视频的结果中。

    音频

    音频元素

    音频支持不仅指对声音的播放,还包括对音频的编辑和合成以及对乐器数字接口等的支持。

    HTML5 Audio元素

    在HTML5中使用”audio“元素来表示,同视频类似,HTML5标准中定义了三种格式:Ogg、MP3和Wav,因为视频内容通常包含音频数据,所以不仅仅是”audio“元素才会使用音频播放,同时,音频的字幕同视频一样,”track“元素也可以用在”audio“元素的字母中,用来显示字幕。

    基础设施

    音频的支持方面还是从输入和输出两个方面着手,对于输入,同视频类似,WebKit使用资源加载器先加载音频文件,之后建立音频元素、管线话引擎相关类,如MediaPlayer类,HTMLAudioElement和WebMediaPlayer类等,同视频不一样的是,视频的输出是GPU中的纹理对象,而音频需要输出到声卡,因此需要打开声卡设备,由于Chromium的沙箱模型机制,所以只能靠Browser进程来打开和关闭声卡设备,下图描述了多进程中如何将音频从Render进程传输到Browser进程,以及WebKit和Chromium中相应的基础设施:
    这里写图片描述
    首先看Render进程,从上玩下介绍如下:

    • WebKit::WebAudioSourceProvider和WebKit::WebAudioSourceProviderClient:最上面两个类是WebKit的Chromium移植接口类,前者提供音频原数据,也就是音频文件中的数据,这里采用“拉”的方式,也就是在ResourceLoader加载数据之后,当且仅当渲染引擎需要新的数据的时候,主动从加载后的数据中拉出数据来进行解码,“provideInput”函数由Chromium实现,由WebKit引擎调用,WebKit::WebAudioSourceProviderClient提供“setFormat”函数,用于让Chromium的媒体播放器设置频道数量、采样率等信息,WebAudioSourceProviderImpl是WebKit::WebAudioSourceProvider的实现类
    • AudioRendererImpl:该类是音频渲染器的实现,并使用AudioRenderSink将音频解码的结果输出到音频设备
    • AudioRendererSink:一个抽象类,用于表示一个音频终端店,能够接收解码后的音频信息,典型的例子就是音频设备
    • AudioRendererMixer:渲染器中的调用类
    • AudioOutputDevice:音频的输出设备,当然只是一个桥接层,因为实际的调用请求是通过下面两个类传送给Browser进程的
    • AudioOutputIPCImpl和AudioMessageFilter:前者将数据和指令通过IPC发送给Browser进程,后者就是执行消息发送机制的类

    下面是Browser进程,从下向上一次介绍:

    • AudioRendererHost:Browser进程端同Renderer进程通信并调度管理输出视频流的功能,对于每个输出流,有相应的AudioOutputStream对象对应,并且通过AudioOutputController类处理和优化输出
    • AudioOutputController:该类控制一个AudioOutputStream对象并提供数据给该对象,提供play、pause、stop等功能,因为它控制这音频的输出结果
    • AudiOutputStream和AudioOutputProxy:音频的输出流类和其子类,AudioOutputProxy是一个使用优化算法的类,它仅在Start()和Stop()函数之间打开音频设备,其他情况下音频设备都是关闭的,AudioOutputProxy使用AudioOutputDispatcher打开和关闭实际的物理音频设备
    • AudioOutputDispatcher和AudioOutputDispatcherImpl:控制音频设备的接口类和实际实现类

    由此可以得出当WebKit和Chromium需要输出解码后的音频数据是,通过从侧自上向下、左侧自下向上的过程,然后使用共享内存的方式将解码后的数据输出到实际的物理设备中。

    Web Audio

    Audio元素能够用来播放各种格式的音频,但是HTML5还拥有更强大的能力来处理声音,这就是Web Audio,该规范提供了搞层次的JavaScript接口,用来处理和合成声音,整个思路就是提供一张图,giant图中的每个节点称为AudioNode,这些节点构成处理的整个过程,虽然实际的处理是使用C/C++来完成,但是Web Audio也提供了一些接口来让Web前端开发者使用JavaScript代码来调用C/C++的实现,WebAudio对于很多Web应用很有帮助,例如它呢能够帮助开发者设计和实时合成出各种音效,根据W3C的Web Audio规范的定义,整个处理过程可以看成一个拓扑图,该图有一个或多个输入源,称为Source节点,中间的所有点都可以看成各种处理过程,它们组成复杂的网,图中有一个最终节点称为“Destination”,它可以表示实际的音频设备,每个图只能有一个该类型的节点,上述图中的所有节点都是工作在一个上下文中,称为AudioContext:
    这里写图片描述
    对于Source1节点,它没有输入节点,hi有输出节点,对于中间的这些节点,它们既包含输入节点也包含输出节点,而对应Destination节点,它只有输入节点,没有输出节点,图中的其他节点都是可以任意定义的,这些即诶但每一个都可以代表一种处理算法,开发者可以根据需要设置不同的节点以处理出不同效果的音频输出,中间这些节点有很多类型,它们的作用也不一样,这些节点的实现通常由C或者C++代码来完成以达到高性能,当然这里提供的接口都是JavaScript接口。Web Audio的绝大多数处理都是在WebKi中完成的,而不需要Chromium过多的参与,除了输入源和输出结果到实际设备,其他同前面的多媒体数据源是一致的。下图的上半部分主要是支持规范中的标准接口,例如AudioBufferSourceNode、AudioContext、DestinationNode和OscillatorNode等类,它们对应上图中规范定义的接口,还有众多类没有绘出,以下重点关注OsicllatorNode类,它需要对音频数据进行大量计算,包括向量的加法、乘法等,同时该节点类需要使用PeriodicWave来计算周期性波形,这里面需要使用到FFT(快速傅立叶变换)算法,因为音频的及时性,网页对性能有非常高的要求,对于Chromium移植,不同平台采用不同的加速算法,在Windows和Linux中使用FFMpeg中的高性能算法,在Android上使用OpenMax DL提供的接口来加速,而在Mac上又是不同的算法:
    这里写图片描述

    MIDI和Web MIDI

    MIDI是一个通信标准,它是电子乐器之间,以及电子乐器与电脑之间的统一交流协议,用以确定电脑音乐程序、合成器和其他电子音响设备互相交换信息与控制信息的方法,同其他的声音格式不同,MIDI不是记录采样信息,而是记录乐器的演奏指令。音频也可以以MIDI格式来存储,但是该格式不是HTML5的标准,所以游览器并没有内置支持它们,为了让MIDI格式的音乐播放出来,可以使用JavaScript代码,这就是MIDI.js,它使用上面提到的WebAudio技术和Audio元素来实现音乐的播放。Web MIDI规范中定义了输入和输出的MIDI设备,如MIDIInput和MIDIOutput,通过MIDIAccess接口分那会到所有枚举的输入和输出设备,MIDIInput主要包含一个接收指令的函数“onMessage”,而MIDIOutput包含一个发送指令的函数“send”,而发送的数据指令就是MIDIEvent,该指令包含一个时间戳和数据,WebKIt和Chromium对于Web MIDI的支持主要包括三个部分,第一是加入JavaScript的绑定,第二是将对MIDI接口的支持从Redner进程桥接到Browser进程,第三是Chromium的具体实现。

    WebRTC

    WebRTC(Web Real Time Communication)技术,中文全称为Web实时通信技术,是一种提供实时视频通信的规范,目前是W3C推荐的规范。

    原理和规范

    构建网络视频通信需要三种类型的技术,其一是视频,其二是音频,其三是网络传输

    • 音视频输入和输出设备:同音视频播放不同,因为它们只是需要输出设备,这里需要输入和输出设备,同时输入使用getUserMedia技术,而输出基本上可以采用音视频播放的基本框架
    • 网络连接的建立:因为视频通信需要不停的传送大量数据,所以需要建立一种可靠的网络连接来让各个参与方传输数据
    • 数据捕获、比那吗和发送:当用户打开设备之后,需要捕获这些数据并对它们进行编码,因为原始数据的数据量太大,然后需要将编码后的数据通过连接传输出去
    • 数据接收、解码和显示:接收来自其他方的数据流并进行解码,然后显示出来,这个跟播放媒体文件的需求比较类似

    下图结合主要组成部分构建一个比较完整的音视频通信过程:
    这里写图片描述
    下面了解一下规范中如何针对上面的描述来定义相应的JavaScript接口,根据W3C推荐的规范草案,主要包括一下几个部分:

    • Media Capture and Streams 规范和WebRTC对它的扩展,这个主要是依赖摄像头和麦克风来捕获多媒体流,WebRTC对它进行扩展,使得多媒体流可以满足网络传输用途,也就是“video”元素可以来源与多媒体流而不仅仅是资源文件
    • 点到点的连接,也就是规范中的RTCPeerConnection接口,它能够建立端到端的连接,两者直接通过某种方式传输控制信息,至于方式并没有进行规定
    • RTCDataChannel接口,通过该接口,通信双方可以发哦是那个任何类型的信息,例如文本或者二进制数据,这个不是必须的,不过这个功能极大的方便了开发者,其主要思想来源与WebSocket
    WebKit和Chromium的实现

    首先了解下WebRTC技术的内部框架和功能模块,下图主要包括三大方面,即语言、视频和传输,它们三个构成WebRTC的主要组成部分,其中iSAC(internet Speech Audio Codec)和iLBC(internet Low Bitrate Codec)是两种不同的音频编码格式,是为了适应互联网的语言传输要求而存在的,前者是针对带宽比较大的情况,后者是针对带宽较小的情况,其中VP8同样是Google提供免费视频格式,传输部分主要是加入了对前面协议的支持模块,在会话管理中,主要使用一个开源项目libjingle来管理,下面部分主要是WebRTC工作时依赖的下层功能的接口,在Chromium游览器中,它会提供相应接口和功能给WebRTC使用:
    这里写图片描述
    上图是WebRTC开源项目的架构图,在Chromium中,通常使用WebRTC项目来完成WebRTC规范的功能,并使用libjingle项目来建立点到点的连接,所有Chromium主要的目的是将WebRTC和libjingle的能力桥接到游览器中来,先看WebRTC规范中建立连接所需要的相关的技术设备,下图是WebKit、Chromium及Chromium中使用libjingle的类的层次图:
    这里写图片描述
    基础设备分成三个层次,首先是WebKit,该部分最上面的类是RTCPeerConnection,该类是对WebRTC连接的接口类,实际上它是从规范中定义的RTCPeerConnection接口文件生成的基本框架,实际真正和JavaScript引擎打交道还需要一个桥接类,该桥接类包含一个实际实现的连接类句柄m_peerHandler,它是这个连接所包含的本地多媒体流和远端对方的多媒体流,场景大致是首先WebKit需要将本地的多媒体流收集起来,通过连接传输给对方,本地可以选择是否通过“video”播放,同时需要接收从对方传输过来的多媒体流,接下来是WebKit的实现类,该类能够满足RTCPeerConnection的功能要求,但是它需要通过不同移植的实现才能完成,因为本身WebKit的WebCore并没有这样的能力,在WebKit的Chromium中同样定义了两个类WebRTCPeerConnectionHandler和WebRTCPeerCOnnectionHandlerClient,根据WebKit的类名定义方式,前者是需要Chroimum来实现,后者则由Chromium调用,并由WebKit来实现,这里主要是应用连接事件的监听函数,所以WebKit能够将它们传递给JavaScript引擎,之后是Chromium的实现类,RTCPeerCOnnectionHandler类继承自WebKit的Chromium移植的接口类,并做了具体的实现,也就是content::RTCPeerConnectionHandler,它同时集成自PeerConnectionHandleBase类,而该类拥有了支持建立连接所需的能力,当然它是依赖于libjingle项目提供的连接能力,libjingle提供了建立和管理连接的能力,支持透过NAT和防火墙设备、代理等建立连接,libjingle不仅支持点到点的连接,也支持多用户连接,同时还包含了连接所使用的MediaStream接口,这是因为Chromium本身不直接使用WebRTC项目提供的接口,而是调用libjingle来建立连接,并使用libjingle提供的MediaStream接口,而libjingle本身则会使用WebRTC项目的音视频处理引擎。
    下面总结下多媒体流,先看下WebKit是怎样支持getUserMedia这个接口的,下图描述了WebKit,以及WebKit的Chroimum移植中所定义的接口:
    这里写图片描述
    最上层的是WebKit支持多媒体流编程接口提供的具体实现类,如NavigatorMediaStream类,而直接同V8JavaScript引擎桥接的类是V8NavigatorUserMediaSuccessCallback,它是一个绑定类,因为getUserMedia接口主要是返回一个MediaStream对象,而MediaStream类可以提供众多访问数据流的接口,而连接的目的就是需要将MediaStream对应的多媒体流传输出去,UserMediaRequest类负责请求创建一个MediaStream对象,在WebKit的Chromium移植中,定义WebUserMediaClient为一个接口类,Chromium需要新建子类来实现这一功能,这就是Chromium中的MediaStreamImpl类。WebKit使用MediaStreamRegistry类来注册和管理对应的类,管理类根据ID信息来识别各个多媒体数据流,在接口层中,Chromium移植使用WebMediaStream类来表示多媒体流,使用WebMediaStreamRegistry类来表示注册管理类,下面的问题是MediaStream接口需要提供各种事件给网页,因为很多实际的工作是在Chromium中来完成的,所以MediaStreamImpl会将这些事件从Chromium传递给WebKit,同时因为Chromium的多进程和沙箱模型,一些工作需要在Browser进程中完成,下图是所描述的跨进程的基础设施:
    这里写图片描述
    IPC左侧部分是Browser进程中的两个主要类,分别是消息处理类和MediaSrteam的管理类,该管理类知道MediaStream对应的网页是什么,并将事件(如创建和销毁等)传回Render进程,右侧是消息派发类,主要帮助MediaStreamImpl类来完成与Browser进程相关的MediaStream消息的传递,MediaStream可以表示本地的多媒体流也可以表示远端的多媒体流,对于本地的多媒体流,需要音频和视频的捕获机制,同时使用上面建立的连接传输给远端,对于远端的多媒体流,需要使用连接来接收数据,并使用到音频和视频的解码能力,下面分成四个部分来分别介绍,首先是音频的捕获机制,下图描述了该机制使用的主要类,当我那工业需要创建多媒体流的时候,MediaStreamImpl会创建音频捕获类WebRtcAudioCapturer类,因为捕获音频需要音频输入设备,所以使用AudioDeviceFactory工厂类创建一个逻辑上的AudioInputDevice对象,另外一个重要的类是WebRtcAudioDeviceImpl,用来表示音频的设备,该类继承自WebRtcAudioDeviceNotImpl类,这其实是继承自libjingle和WebRTC项目中的抽象接口的一个桥接类,用来表示它们需要的音频设备,包括输入鼠辈,同样因为Render进程不能访问音频输入设备,所以需要IPC来完成一个功能,Browser进程的AudioInputController会控制和访问设备,而AudioInputDeviceManager可以管理和控制所有输入设备:
    这里写图片描述
    其次是处理远程多媒体流中的音频解码和播放功能,下图是Chromium处理远端音频流所需要的一些主要类及关系图,这里不涉及连接如何接收传输的数据,因为Chromium是使用libjingle和WebRTC项目来完成连接的功能,Chromium使用WebRtcAudioRender类来完成音频渲染,该桥接类会被WebMediaPlayer作为渲染音频的实现类,其作用主要是将MediaStream的数据同实际的音频渲染类结合起来:
    这里写图片描述
    再次是从视频输入设备请求捕获本地视频流,下图是该功能依赖的一些主要类:
    这里写图片描述
    实线右侧Render进程中的设施,同样是MediaStreamImpl类发起,有辅助工厂类MediaStreamDependencyFactory帮助创建一个RtcVideoCapaturer,用来获取视频,该类有两个作用,其一是是吸纳linjingle和WebRTC项目中的接口类,因为需要薯片输入的实现,这个同音频部分类似,另外就是将调用请求交割一个代理类来完成(RtcVideoCaptureDelegate类),分别是管理类VideoCaptureImplManager和视频捕获类VideoCaptureImpl,并包括一个发送消息到Browser进程的辅助类,在Browser进程使用控制类VideoCaptureController来获取VideoCaptureDevice,该类会使用摄像头等视频输入设备。最后是处理远端多媒体流中的视频解码和播放功能,当MediaStreamImpl对象接收到远端的多媒体流之后,它会使用WebRTC来会视频数据进行解码,因为可以使用硬件来解码,提供了处理的性能:
    这里写图片描述
    把WebRTC整个过程综合起来分析如下图,可以有一种更为整体和直观的感受:
    这里写图片描述

    展开全文
  • Android多媒体应用开发实战详解

    千次下载 热门讨论 2014-07-10 21:57:31
    《Android多媒体应用开发实战详解:图像、音频、视频、2D和3D》 提醒:假如百度云分享链接失效,请联系站长,我会补上的。 《Android多媒体应用开发实战详解:图像、音频、视频、2D和3D》 提醒:假如百度云分享...
  • 多媒体技术基础(第3版)》在第2版的基础上,《多媒体技术基础(第3版)》对部分章节的内容做了更新,增加了MPEG-4AVI/H.264和多媒体传输方面的内容。为保持多媒体技术基础课程内容的完整性,《多媒体技术基础》仍由四...
  • 多媒体API

    千次阅读 2012-05-09 23:07:27
    多媒体API 包括 播放和录制音频和视频, 拍照。 Android 支持的媒体格式可从网址 http://developer.android.com/guide/appendix/media-formats.html 找到. 一 . 在了解多媒体之前,需要先了解SD卡, 你可能注意...

    从本博文开始, 将针对Android 中包括的API 来写。

    多媒体API 包括 播放和录制音频和视频, 拍照。

    Android 支持的媒体格式可从网址 http://developer.android.com/guide/appendix/media-formats.html  找到.

    一 . 在了解多媒体之前,需要先了解SD卡,  你可能注意到SD卡下有一个名为DCIM 目录,这是相机图像的目录,

    将存储数码图像的DCIM  目录放在SD卡目录下,这是一种行业标准,在DCIM 目录下创建一个表示相机的目录,这也是一种行业标准,该目录格式为123ABCDE, 由3个数字和5个字母组成.

    从android 2.2起,SD卡有多种标准化的目录名称, 如下表所示

    SD卡上的标准化目录
     目录常量       说           明       模拟器中SD卡顶级目录下的目录   
    DIRECTORY_ALARMS

    当android查找音频文件以用于闹钟时,它在

    这个标准目录中查找

                                   Alarms
    DIRECTORY_DCIM  查找使用相机拍摄的照片和视频的行业标准目录                                DCIM
    DIRECTORY_DOWNLOADS  保存用户下载的文件的标准目录                                Download
    DIRECTORY_MOVIES  查找电影文件时,在此标准目录中查找                                Movies
    DIRECTORY_MUSIC  查找音频文件以用作用户常听的音乐时,在此标准目录中查找                                Music
    DIRECTORY_NOTIFICATIONS  查找音频文件以用作通知时,在此标准目录中查找                                Notifications
    DIRECTORY_PICTURES  查找不是使用相机拍摄的图像文件时,在标准目录中查找                                Pictures
    DIRECTORY_PODCASTS  查找音频文件以用作播客时,它在此标准目录中查找                                 Podcasts
    DIRECTORY_RINGTONES  查找音频文件以用作铃声时,它在此标准目录中查找                                 Ringtones
         

    查找目录的方法是Environment.getExternalStoragePublicDirectory(String   type), 其中type 参数是表中左边一列的常量

    二.  下面介绍播放音频、视频

    1 . 音频  (待完善)

    2.  视频

    注意一下这种写法  videoView.setVideoURI(Uri.parse("file://"+ Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES) + "/movie.mp4"));

    播放SD卡电影文件目录下mp4文件。

     以下是播放res\raw 目录下视频test.mp4 的写法

    private String rawUri = = "android.resource://" + getPackageName() + "/" + R.raw.test;;//程序自带raw目录下视频文件

    vv.setVideoURI(Uri.parse(rawUri));

    vv.start();

     附: 精通 Android 3 书中代码 下载网址  http://www.androidbook.com/akc/display?rl=ShowAttachmentsIMPURL&reportId=3540&downerUserId=satya&order_by_format=name

    本文相关代码 在 ProAndroid3_Ch19_Media.zip 文件

    展开全文
  • 多媒体技术基础知识(4学时) 多媒体计算机硬件系统(2学时) 多媒体计算机软件系统(2学时) 超文本与超媒体(2学时) 多媒体数据压缩技术(4学时) 多媒体应用技术基础(4学时) 图像处理技术(Photoshop)-1 动画制作技术...
  • 凌波多媒体电子教室6.95和6.96破解免加密狗版

    千次下载 热门讨论 2012-11-15 15:57:39
    凌波多媒体电子教室6.95版和6.96原官网破解版,附6.95和6.96破解文件,另加一个注册机,都是我们自己使用过的,绝对能用!由于官网根本没有提供6.96这个原版,所以使用6.95安装,使用6.96版的文件替换即可,6.96办...
  • 多媒体教学网V9.0经过严格的软、硬件测试和大规模应用测试过程,全面支持 Windows 系列操作系统,包括 Windows 9X、Windows Me、Windows NT 4.0、Windows 2000 、Windows XP、Windows Server 2003 以及 Windows PXE ...
  • 实验1 基于MFC的多媒体播放器的设计与实现 word文档下载 一、实验目的: 利用MFC在VC++或其它语言环境下设计一个多媒体播放器,进一步熟悉与掌握多媒体编程的基本技术与方法。 二、实验要求: 1、制作一个如下图的...

    实验1  基于MFC的多媒体播放器的设计与实现

    • 实验目的:

    利用MFC在VC++或其它语言环境下设计一个多媒体播放器,进一步熟悉与掌握多媒体编程的基本技术与方法。

    • 实验要求:

    1、制作一个多媒体播放器界面,并尽量实现全部或绝大部分功能。

    2、用.mp3、.avi等格式文件进行播放测试,并获取播放效果图。

    3、完成ABOUTBOX的版权信息

    4、完成并测试程序后将源程序文件夹压缩后上传网络课堂,请确保程序的正确性与可执行性,老师通过执行你的程序从而给你计算本次实验成绩。

    5、认真完成实验报告,必须包括实验目的,实验工具、设计框图、实验步骤、所完成的主要设计内容与方法、实验分析与总结等内容。
    实验指导与基本步骤:

    使用VC++6.0的AppWizard、ClassWizard和其中的各种控件可以方便地建立各种应用程序。但是想要实现更高级更复杂的功能,就要借助丰富的ActiveX控件资源。本实验计划使用VC++6.0自带的一个ActiveX控件——ActiveMovieControl Object,来设计多媒体播放器。此多媒体具有一般的播放功能,能播放:*.mp3,*.wma,*.mdi,*.wav,*.avi,*.dat等文件,还有Repeat功能。

    1、注册控件:在windows“运行”里写入:regsvr32 msdxm.ocx 单击确定。

    2、打开VC6.0,在Projects下选择MFC AppWizard(exe),并取名VedioPlayer,然后建立基于对话框的应用程序。最后删除“确定”按钮,保留“取消”按钮。

    3、打开Resource View,选择其中的对话框,打开其中的主对话框,去掉对话框上的“确定”按钮,保留“取消”,将Caption改为“退出”。然后再在上面加上几个按钮,ID和Caption分别为

    IDC_OPEN,打开;

    IDC_PLAY,播放;

    IDC_PAUSE,暂停;

    IDC_STOP,停止;

    IDC_CLOSE,关闭;

    IDC_LOWER,-;

    IDC_UPPER,+;

    IDC_FULLSCREEN,全屏;

    。。。。。。

    4、加入ActiveMovieControl控件。打开Projects->Add to Project->Components and Controls->Registered ActiveX Controls对话框,选择其中的ActiveMovieControl Object, Insert,OK之后,会发现控件面板上多了一项ActiveMovieControl Object,将它选中,直接放在对话框上,并拖成合适大小。

    5、ActiveMovieControl控件设置变量m_ActiveMovie。点中它,按Ctrl+W打开ClassWizard为它添加变量m_ActiveMovie。

    6、为程序添加消息处理函数。打开ClassWizard,为各个按钮加入消息处理函数。在MediaPlayerDlg.cpp文件里为各消息处理函数添加代码,部分代码如下:

    void CVediorDlg::OnClose()

    {

    m_ActiveMovie.CloseWindow();//关闭窗口

    }

    void CVedioPlayerDlg::OnOpen()

    {

    char szFileFilter[]=

    "Mp3 File(*.mp3)|*.mp3|"

    "Wma File(*.wma)|*.wma|"

    "Video File(*.dat)|*.dat|"

    "Wave File(*.wav)|*.wav|"

    "AVI File(*.avi)|*.avi|"

    "Movie File(*.mov)|*.mov|"

    "Media File(*.mmm)|*.mmm|"

    "Mid File(*.mid;*,rmi)|*.mid;*.rmi|"

    "MPEG File(*.mpeg)|*.mpeg|"

    "All File(*.*)|*.*||";//文件类型过滤

    CFileDialog dlg(TRUE,NULL,NULL,OFN_HIDEREADONLY,szFileFilter);

    if(dlg.DoModal()==IDOK){

    CString PathName=dlg.GetPathName();

    PathName.MakeUpper();//这个函数可以将CString字符转化为一个大写的字符串

    m_ActiveMovie.SetFileName(PathName);

    }

    }

    void CVedioPlayerDlg::OnPlay()

    {

    m_ActiveMovie.Run();//播放文件

    SetTimer(0,20,NULL);//设置定时器

    //0:计时器的名称;20:时间间隔,单位是毫秒;NULL:使用OnTimer函数。

    }

    void CVedioPlayerDlg::OnStop()

    {

    m_ActiveMovie.Stop();//停止播放文件

    KillTimer(0);//关掉定时器

    }

    void CVedioPlayerDlg::OnPause()

    {

    m_ActiveMovie.Pause();//暂停播放

    }

    void CVedioPlayerDlg::OnUpper()//增加音量

    {

    long Volume=m_ActiveMovie.GetVolume();

    m_ActiveMovie.Pause();

    m_ActiveMovie.SetVolume(Volume+100);

    m_ActiveMovie.Run();

    }

    void CVedioPlayerDlg::OnLower()//减少音量

    {

    long Volume=m_ActiveMovie.GetVolume();

    m_ActiveMovie.Pause();

    m_ActiveMovie.SetVolume(Volume-100);

    m_ActiveMovie.Run();

    }

    void CVedioPlayerDlg::OnFulscreeen()//全屏播放

    {

    m_ActiveMovie.Pause();

    m_ActiveMovie.SetFullScreenMode(true);

    m_ActiveMovie.SetMovieWindowSize(SW_SHOWMAXIMIZED);

    m_ActiveMovie.Run();

    }

    这里需要注意的是,下面的函数OnTimer()需通过ClassWizard(Ctrl+W)来添加,不能直接复制:

     

    void CVedioPlayerDlg::OnTimer(UINT nIDEvent)

    {

    double CurrentPos=m_ActiveMovie.GetCurrentPosition();

    if(CurrentPos==0&&isRepeat)//如果当前是文件的起始位置而且为重复播放状态

    m_ActiveMovie.Run();

    CDialog::OnTimer(nIDEvent);

    }

    7、为使播放器具有重复播放功能,需在头文件VedioPlayerDlg.h 加入控制变量BOOL isRepeat;类型可为Private。

    同时修改OnInitDialog()函数:

    BOOL CMediaPlayerDlg::OnInitDialog()

    {

    CDialog::OnInitDialog();

    isRepeat=FALSE;

    ……

    }

    本文实现的MFC播放器如下图所示

    所有功能均已实现,点击获取代码和文档 

    展开全文
  • 有权限我能手动删除这个多媒体文件, 请帮忙看下是不是代码问题,代码如下: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; namespace FileStream...
  • C#版本多媒体定时器

    热门讨论 2011-12-01 09:31:02
    MmTimer 是一个多媒体定时器的C#简单封装。 使用这个定时器,你可以得到1ms精度的单次延时或周期定时。最初是想用来做播放midi文件的时钟,当然你也可以用它来做任何它能做到的事情。
  • Android多媒体浅析

    2012-12-29 19:29:11
    1. 系统如何选择多媒体引擎 2. 引擎如何选择编解码器 3. 分离器如何分离音视频 4. 视频解码播放过程如何使用OMX IL 5. 音频解码播放过程与ALSA的关系 1. 系统如何选择多媒体引擎 多媒体系统...

    发现Android影音系统超复杂的,个人水平有限,关注以下几个问题:

    1. 系统如何选择多媒体引擎

    2. 引擎如何选择编解码器

    3. 分离器如何分离音视频

    4. 视频解码播放过程如何使用OMX IL

    5. 音频解码播放过程与ALSA的关系


    1. 系统如何选择多媒体引擎

    多媒体系统自上而下可分为三类,

    • 上层应用软件,就是在Android市场里下载的到的多媒体播放软件如Mobo player, Rock player等。
    • 系统级多媒体引擎,Android 2.3默认的是Stagefright,取代了之前繁琐的Opencore。
    • 系统级多媒体插件OMX IL层,用于音视频编解码。

    Android系统启动时开启本地服务MediaPlayerService,全权负责多媒体控制。

    上层调用setDataSource(),根据音视频文件的路径名称url选择合适的播放引擎。

    getPlayerType()选择引擎的依据主要有两个:

    1)url的开头名称如rtsp://, http://

    2)  property_get()读取init.rc脚本相关信息。

    选择成功后创建,本文讨论Android2.3默认的多媒体引擎Stagefright,它把具体任务全部交由AwesomePlayer实现。

     

    2. 引擎如何选择编解码器

    上层调用prepareAsync(),自上而下一直到AwesomePlayer开启一个准备音视频的事件,这个事件完成媒体播放前两大工作-即音视频分离和编解码配置。

    先说编解码配置,通过findMatchingCodecs()找到合适的解码器,依据仍然是音视频文件的路径名称url。

    具体地,在OMXCodec.cpp里有一个数据结构CodecInfo,

    struct CodecInfo {

        const char *mime;     // 通过url得到的音视频信息

        const char *codec;    // 该多媒体引擎支持的编解码器

    };

    比如有一个音频文件jay.mp3存放于U盘根目录下,即url: /mnt/extsd/jay.mp3,

    - 首先通过url得到mine: audio/mpeg,

    - 然后通过mine找到匹配的codec: MP3Decoder,即MP3解码器。

    - 找到解码器后,将其作为OMX的节点创建和配置。

     

    3. 分离器如何分离音视频

    finishSetDataSource_l()分离音视频轨道。

    1)通过url得到数据源dataSource。

    2)根据dataSource选择合适的分离器。

    3)  将分离的音频源和视频源放入相应的全局变量里,以便播放时使用。

     

    4. 视频解码播放过程如何使用OMX IL

    视频播放部分参考博文 http://www.cublog.cn/u1/57901/showart_2423206.html

    整个流程概括起来,就是把分离的视频源放入onVideoEvent事件,经OMX解码处理并转换成RGB格式后输出屏幕。

    上层播放音视频调用start()即可,殊不知引擎在其中完成了巨大的工作量,先说视频,

    drainInputBuffer()和fillOutputBuffer调用了OMX IL层进行视频解码,这里OMX节点mNode就是先前提到的解码器建立的。

    mOMX->emptyBuffer和mOMX->fillBuffer是两个核心的回调函数,其实质如下图。

     

     5. 音频解码播放过程与ALSA的关系

    AwesomePlayer把音频播放的任务交给AudioPlayer,AudioPlayer创建AudioTrack,AudioTrack线程与AudioFlinger服务线程通过类似管道的机制进行数据通信,AudioFlinger调用抽象层进入ALSA架构,openOutputStream()输出音频数据流。

    关于音频播放系统参考博文 http://blog.csdn.net/DroidPhone/article/details/5941344

    展开全文
  • 我在代码中的多媒体列表中加入手风琴效果后,每次点击都会出现这样的bug![图片说明](https://img-ask.csdn.net/upload/201501/31/1422695233_404612.png),没点击前是这样的,![图片说明]...
  • 通过对Android多媒体实战开发技术,如图像、音频、视频、2D和3D的详细讲解,让读者学会如何在应用开发中应用多媒体技术为自己的APP增加炫酷的效果,特别是Android5.0新出现的API这些特性是目前市面上的一些书籍所...
  • !... ...以下是我的3个问题: ...有大神能帮帮我吗? ...3、或者有没有谁实现过微信公众号以上截图描述的用java实现的多媒体文件上传功能,有实现过的话,共享以下代码啊!本人感激不尽!。 求大神帮帮忙!
  • VC多媒体定时器实例

    热门讨论 2010-04-17 17:18:39
    利用VC多媒体定时器编写的定时器小程序,可供用VC进行精确定时或者定时控制,实时控制的编程参考。内附详细的过程说明
  • 多媒体技术 PDF 清晰

    2008-12-16 10:10:31
    本书全面系统的介绍了多媒体技术的各个方面的知识。 第二章 数字化多媒体系统 第三章 常见媒体类型 第四章 多媒体数据压缩 ……
  • Android多媒体开发技术

    千次阅读 2018-05-06 18:20:09
    周末参加了线下安卓巴士论坛组织的“安卓开发者的修炼之道”,几位嘉宾分享的...第二位嘉宾何俊林,前爱奇艺多媒体开发,据说活动现场很多他的粉丝,都是慕名而来见大神的。分享的主题是《Android多媒体开发技术》。...
  • Linux多媒体开发基础

    千次阅读 2016-09-06 11:08:03
    名词解释:gstreamer GStreamer 是用来构建流媒体应用的开源多媒体框架(framework),其目标是要简化音/视频应用程序的开发,目前已经能够被用来处理像 MP3、Ogg、MPEG1、MPEG2、AVI、Quicktime 等多种格式的多媒体...
  • Android多媒体真烦人

    千次阅读 2012-02-15 00:06:05
    这几天有点郁闷,搞多媒体这块。这个东西看起来好像很简单,我了个去。在别人眼中好像做应用很简单的样子。一个程序三两天就要出来。真有点无语。看来做应用没什么地位啊。  嘴皮子说大家都会,查数据库啊,获取...
  • 与嵌入式软件开发工程师(BSP)的题目类型来说,多媒体&智能应用的笔试题在前面的选择题上类型差不多,主要是两条简答题。前者是偏向于Linux驱动方面,后者是偏向于视频/音频的采集或者编码方面。总体来说,大差...
  • 多媒体技术

    2009-04-18 17:50:00
    多媒体技术所处理的文字、数据、声音、图像、图形等媒体数据是一个有机的整体,而不是一个个“分立”的信息类的简单堆积,多种媒体间无论在时间上还是在空间上都存在着紧密的联系,是具有同步性和协调性的群体。...
  • 多媒体定时器

    千次阅读 2016-08-18 10:24:15
    一、简介 在工业生产控制系统中,有许多需要定时完成的操作,如数据采集程序。Win32提供了一个基于消息机制的定时器,使用SetTimer函数创建一个内存对象,设定间隔时间,当到达要求的间隔时,计时器对象发送一个WM_...
  • 多媒体理论

    2020-01-02 22:38:47
    多媒体理论媒体媒体的含义媒体的种类多媒体多媒体的定义多媒体数据处理过程多媒体技术多媒体技术的定义多媒体技术的特征多媒体系统结构多媒体系统的定义多媒体系统的层次结构多媒体系统的基本组成多媒体硬件系统声音...
  • 多媒体重定向

    千次阅读 2015-06-26 09:43:47
    桌面云视频播放的一种方式,多媒体重定向。  远程桌面连接的多媒体重定向功能在客户端和主机端都支持时启用,其主要作用为在主机端播放的文件在客户端进行解码播放,而不是直接传送bitmap。其主要优势在于: ...
  • HTML多媒体

    2018-03-19 19:46:32
    web上的多媒体是指音效、音乐、视频和动画,现代网络浏览器已经支持很多多媒体格式。 在HTML5之前,主要提供两种元素进行多媒体的展示,一个是&lt;embed&gt;标签,另一个是&lt;object&gt;标签。 ...
  • 多媒体框架

    千次阅读 2014-05-27 15:53:05
    多媒体框架
  • 多媒体播放器

    2013-08-20 23:33:29
    xine(官方发音[ksi:n])是一个类UNIX操作系统下的多媒体播放引擎,遵循GPL协议。xine 基于一个支持不同前端播放器应用程序的公用库 (xine-lib) 。 xine的一个重要特性具有手动音视频同步的功能。 xine 使用源自...
  • Android多媒体

    2013-05-02 16:33:44
    Android多媒体之AudioRecord   AudioRecord API: http://www.cnblogs.com/over140/archive/2011/05/31/2063969.html 简单示例 http://blog.csdn.net/xiaomao5200/article/details/7716216 ...
  • 多媒体规范

    千次阅读 2011-09-28 13:04:37
    http://www.wotsit.org/list.asp?fc=3

空空如也

1 2 3 4 5 ... 20
收藏数 42,497
精华内容 16,998
关键字:

多媒体