playback_playbackrate 移动端无效 - CSDN
精华内容
参与话题
  • 视频播放器Playback.zip

    2020-07-17 17:52:38
    Playback 是一个基于 Atom Shell 和 Node.js 开发的视频播放器。 标签:Playback
  • Android -- MediaPlayer之Media Playback基础介绍 多媒体回放 Android多媒体框架包含了对各种常见媒体类型文件的播放支持,所以我们可以简单地将音频、视频、图片整合进我们的应用程序之中。我们可以使用...

    Android -- MediaPlayer之Media Playback基础介绍


    文章翻译自Android官方文档:http://www.android-dev.cn/guide/topics/media/mediaplayer.html#viacontentresolver

    多媒体回放


            Android多媒体框架包含了对各种常见媒体类型文件的播放支持,所以我们可以简单地将音频、视频、图片整合进我们的应用程序之中。我们可以使用MediaPlayer播放存储在应用程序中的原始资源,也可以播放文件系统中的独立文件,也可以播放通过网络获取的数据流。

            这篇文档向我们展示了如何写出一个拥有良好表现和体验的用户与系统交互的多媒体程序。

    提醒:我们只能在标准输出设备上播放音频数据。当前,这些设备是手机设备的扬声器或者蓝牙头戴式耳机。我们不能在通话过程中播放声音文件。


    基础


            下面这些类是Android framework中用来播放声音和视频的:

    MediaPlayer:该类是播放声音和视频的主要API

    AudioManager:该类管理一个设备上的音频数据和音频输出


    清单声明


            在使用MediaPlayer开始开发你的应用之前,确保你的清单文件中有适当的声明(权限声明),让你允许使用一些关联的特性。

    • 网络权限-如果你正在使用MediaPlayer处理网络内容,你的应用程序必须需要网络接入。
    <uses-permission android:name="android.permission.INTERNET" />
    • Wake Lock 权限-如果你的播放程序需要保持屏幕常亮或使设备不进入睡眠,或者调用了 MediaPlayer.setScreenOnWhilePlaying() 、MediaPlayer.setWakeMode() 方法,你就必须请求这个权限。
    <uses-permission android:name="android.permission.WAKE_LOCK" />

    使用MediaPlayer


            媒体框架的一个最重要的部分就是MediaPlayer类。该类的一个实例可以通过极少的步骤去获取、解码和播放音视频。它支持几种不同的媒体资源,例如:
    • 本地资源
    • 内部URI资源, 例如通过某个Content Resolver获取的URI
    • 外部URL资源(流)
            Android支持的媒体格式列表,可以参照Android Supported Media Formats文档。

            这里是一个如何去播放本地原始资源(保存在应用程序的res/raw/目录)的音频的例子:
    MediaPlayer mediaPlayer = MediaPlayer.create(context, R.raw.sound_file_1);
    mediaPlayer.start(); // no need to call prepare(); create() does that for you
            这个例子中,一个原始资源是一个系统不会以任何特定方式去解析的文件。但是,该资源的内容不应该是原始音频。它应该是一个被正确编码且以Android支持的格式封装成的媒体文件。

            这里是一个播放通过URI获取的系统本地文件(通过Content Resolver获取)的例子:
    Uri myUri = ....; // initialize Uri here
    MediaPlayer mediaPlayer = new MediaPlayer();
    mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
    mediaPlayer.setDataSource(getApplicationContext(), myUri);
    mediaPlayer.prepare();
    mediaPlayer.start();
            播放一个通过HTTP协议传输的远端流的做法看起来是这样的:
    String url = "http://........"; // your URL here
    MediaPlayer mediaPlayer = new MediaPlayer();
    mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
    mediaPlayer.setDataSource(url);
    mediaPlayer.prepare(); // might take long! (for buffering, etc)
    mediaPlayer.start();
    提醒:如果你是靠传入一个URL地址去引入在线的媒体文件,你必须保证它是可以被渐进载入的。
    警告:在调用setDataSource()时,你必须捕获或对外传递IllegalArgumentException和IOException异常,因为你当前引用的文件也许是不存在的。

    异步Preparation


            使用MediaPlayer在条理上是简单易懂的。但是当我们将它整合进一个典型的Android应用中时,记住其他的一些必要事情是很重要的。例如,prepare()调用也许会花费很长的时间去执行,因为它会牵扯到媒体数据的获取和解码。所以,对于那些要花费较长时间执行的方法,我们不能在应用程序的UI线程中调用它。如果我们这样做,会导致UI挂起,直到方法得到返回为止;这是一个非常差的用户体验,同时也会导致一个ANR错误。即使你认为你的资源加载非常快,也必须记住UI中任何花费超过0.1秒时间响应的操作都会导致明显的卡顿,这会给用户带来你的应用程序运行很慢的印象。
            为了避免阻塞你的UI线程,我们应该创建另外一个线程准备你的MediaPlayer对象,并完成的时候去通知主线程。然而,尽管你可以自己写线程逻辑,但调用MediaPlayer框架提供的prepareAsync()方法来完成这项任务会更加方便,也更加通用。该函数会在后台开启准备媒体数据并立刻返回。当媒体数据准备完成时,通过setOnPreparedListener() 方法配置的MediaPlayer.OnPreparedListener回调的onPrepared()函数就会被调用。

    管理状态


            我们需要关注的关于MediaPlayer的另一个方面就是它是基于状态的。也就是说,写代码时我们必须时刻注意MediaPlayer拥有自己的内部状态,因为只有当播放器在某个特定的状态时,一个确定的操作才是合法的。如果你在错误的状态执行一个操作,系统也许会抛出一个异常,或者出现其他令人不快的行为。
            MediaPlayer类的介绍文档展示出了一个完整的状态图,它清楚表明了某个方法会将MediaPlayer从一个状态移动到另一个状态。举个例子,当你创建MediaPlayer时,它处于Idle状态。在这个点,我们需要调用setDateSource()初始化该对象,将它转换到Initialized状态。之后,我们必须调用prepare()或者prepareAsync()方法去准备它。当MediaPlayer准备完成后,它将会进入Prepared状态,这意味着你可以调用start()方法开始播放媒体数据。这时,正如图中所示,我们可以通过调用start()、pause()和seekTo()方法让MediaPlayer在Started、Paused和PlaybackCompleted状态之间移动。要注意当你调用stop()时,直到你再次对MediaPlayer调用函数进行prepare后,我们才能再次调用start()。
            我们在写与MediaPlayer交互的代码时,要时刻将状态图记在心里,因为在错误的状态调用它的方法,是一些缺陷产生的普遍原因。

    释放MediaPlayer


            一个MediaPlayer实例会占用宝贵的系统资源。因此,我们需要花费额外的精力确保应用中不会持有一个无需再被使用的MediaPlayer实例。当我们使用它完成任务时,总是要调用release()方法确以保任何分配给它的系统资源能被正确地释放。举个例子,如果我们正在使用MediaPlayer,此时你的activity收到了一个onStop()调用;我们必须释放这个MediaPlayer,因为当你的activity不再跟用户交互时,持有它是没有意义的(除非你正在后台播放媒体文件,这将会在下一节讨论)。当你的activity被resume或restart时,在重新回放之前,我们需要创建一个新的MediaPlayer并重新prepare它。
            下面是释放并废弃我们的MediaPlayer的方法:
    mediaPlayer.release();
    mediaPlayer = null;
            举个例子,考虑这样一种可能发生的问题:当你的activity被停止时,你没有释放当前的MediaPlayer;但是在activity再次启动时,你又创建了一个新MediaPlayer。正如你所知道的,当用户改变了屏幕方向(或者以其他的方式改变了设备配置),系统会通过重启activity来处理这种情况(默认方式);所以,当用户频繁这样做时,我们也许会很快地耗尽所有的系统资源,因为每次方向改变时,我们都创建了一个新的你从没释放的MediaPlayer。
            
            正如那些音乐程序所表现的那样,你也许想知道当用户离开了你的activity,而我继续后台播放媒体文件时会发生什么。这种情况下,你需要的是一个被Service控制的MediaPlayer,我们接下来就讨论这部分。

    在Service中使用MediaPlayer


            如果你希望当你的应用程序不再屏幕当前显示时 ,让它在后台继续播放媒体文件;也就是说,你希望用户当前在与其他应用交互时,继续播放动作-这时,你必须启动一个Service,并在Service中控制MediaPlayer实例。这一步,我们应当小心;因为,用户和系统对应用程序如何启动一个后台服务与剩下的系统交互有着不同的期望。如果你的应用没有达成这些期望,就会给用户带来不好的体验。这一部分主要描述了你需要注意的内容,并且对如何实现它们提供了建议。

    异步运行


            首先,与Activity一样,所有在Service中完成的工作默认都是在一个单独的线程中进行的-事实上,如果你在同一个应用中运行一个Activity和一个Service,它们都默认工作在主线程中。因此,服务必须要快速的处理来到的intent,并且在响应它们时不应该进行冗长的计算。如果你需要处理任何繁重的工作,或者存在阻塞的调用时,你都必须异步地处理这些任务:可以是在你自己实现的新线程中,或者是使用framework中提供的用于异步执行的工具。
            例如,当你在主线程中使用MediaPlayer时,你应该调用prepareAsync(),而不是prepare();并且要实现一个MediaPlayer.OnPreparedListener回调用于当准备工作完成时去提醒你可以开始播放了。例如:
    public class MyService extends Service implements MediaPlayer.OnPreparedListener {
        private static final String ACTION_PLAY = "com.example.action.PLAY";
        MediaPlayer mMediaPlayer = null;
    
        public int onStartCommand(Intent intent, int flags, int startId) {
            ...
            if (intent.getAction().equals(ACTION_PLAY)) {
                mMediaPlayer = ... // initialize it here
                mMediaPlayer.setOnPreparedListener(this);
                mMediaPlayer.prepareAsync(); // prepare async to not block main thread
            }
        }
    
        /** Called when MediaPlayer is ready */
        public void onPrepared(MediaPlayer player) {
            player.start();
        }
    }

    处理异步错误


            同步操作中,一般使用异常或错误码来通知程序错误。但是任何时候,你在使用异步资源时,都要保证你的应用程序可以被正确地告知有错误发生。在MediaPlayer这个例子中,你可以通过实现MediaPlayer.OnErrorListener回调并将它设置给MediaPlayer实例来完成:
    public class MyService extends Service implements MediaPlayer.OnErrorListener {
        MediaPlayer mMediaPlayer;
    
        public void initMediaPlayer() {
            // ...initialize the MediaPlayer here...
    
            mMediaPlayer.setOnErrorListener(this);
        }
    
        @Override
        public boolean onError(MediaPlayer mp, int what, int extra) {
            // ... react appropriately ...
            // The MediaPlayer has moved to the Error state, must be reset!
        }
    }
            我们要记住,当一个错误发生时,MediaPlayer会移动到Error状态,这是很重要的;再次使用它之前,我们必须重置这个对象。

    使用唤醒锁


            在设计后台播放媒体资源的应用时,设备可能会在你的服务运行期间进入睡眠状态。因为设备睡眠时,Android系统会尝试保存电量,它会去关掉任何非必须的手机特性,包括CPU和WiFi硬件。因此,如果你的服务正在播放音乐,你会想去阻止系统妨碍你的回放过程。
            为了保证你的服务能在这些条件下继续运行,你必须使用“唤醒锁”。唤醒锁可以向系统表明,你的应用程序正在使用一些设备特性,即使手机处于空闲状态,它们也需要保持可以获取的状态。
            注意:你应该仅在你需要的时候使用唤醒锁,因为,它们会显著地降低设备电池的寿命。
            为了确保当你的MediaPlayer正在播放时CPU会继续运行,在初始化MediaPlayer时,你需要调用setWakeMode()方法。一旦这样做,MediaPlayer正在播放时会持有一个特定的锁,播放暂停或停止时都需要释放这个锁:
    mMediaPlayer = new MediaPlayer();
    // ... other initialization here ...
    mMediaPlayer.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK);
            然而,这个示例中获取到的锁只能保证CPU保持唤醒。如果你正在通过网络且使用WiFi载入一个网络媒体,你也许还需要持有一个WiFi Lock,你必须手动请求和释放它。所以,当你开始通过一个远程URL准备MediaPlayer时,你应该创建并请求WiFi Lock。例如:
    WifiLock wifiLock = ((WifiManager) getSystemService(Context.WIFI_SERVICE))
        .createWifiLock(WifiManager.WIFI_MODE_FULL, "mylock");
    
    wifiLock.acquire();
            当你暂停或停止媒体播放,或者你不再需要使用网络时,你应该释放这个锁:
    wifiLock.release();

    作为前台服务运行


            Service通常被用来执行后台服务,例如收发邮件、同步数据、下载内容,etc。这些例子中,用户不会明显察觉到这些服务的执行,并且他们甚至不会注意到这些服务是否被中断、重启。
            但是考虑一个服务正在播放音乐,用户明显意识到它的存在,此时任何的中断操作(是该服务中断)都会影响到体验效果。除此之外,这是一个在它的运行过程,用户都希望与之交互的服务。这时,该服务应该作为“前台服务”运行。一个前台服务在系统中拥有更高的重要性等级-系统将几乎不会杀死该服务,因为它对用户而言是非常重要的。当服务运行在后台时,我们需要提供一个状态栏让用户看到当前有服务正在运行,这也允许用户可以打开一个用来与该服务交互的Activity界面。
            为了将你的服务转换成前台服务,你必须为状态栏创建一个Notification(通知),并且在服务中调用startForeground()函数。例如:
    String songName;
    // assign the song name to songName
    PendingIntent pi = PendingIntent.getActivity(getApplicationContext(), 0,
                    new Intent(getApplicationContext(), MainActivity.class),
                    PendingIntent.FLAG_UPDATE_CURRENT);
    Notification notification = new Notification();
    notification.tickerText = text;
    notification.icon = R.drawable.play0;
    notification.flags |= Notification.FLAG_ONGOING_EVENT;
    notification.setLatestEventInfo(getApplicationContext(), "MusicPlayerSample",
                    "Playing: " + songName, pi);
    startForeground(NOTIFICATION_ID, notification);
            当你的服务运行在前台时,你配置的notification在设备的通知区域是可见的。如果用户选择了这个notification,系统就会请求你提供的PendingIntent。下面的例子中,它会打开一个Activity(MainActivity)。
            图1展示了你的notification是如何展现给用户的:


    图1:前台服务notification的截图,展示了状态栏通知的图标(左)以及其展开后的视图(右)
            你应该仅在你的服务确实在展现一些用户感兴趣的事物时,才持有“前台服务”状态。一旦你不在需要,你应该通过调用stopForeground()释放它:
    stopForeground(true);
            如果需要更多信息,可以看有关ServiceStatus Bar Notification的文档。

    处理音频焦点


            尽管任意给定的时刻只有一个Activity可以运行,但Android是一个多任务的系统环境。这就给那些要使用音频的应用提出了一个特殊的挑战,因为系统只存在一个音频输出,多个不同的媒体服务也许会竞争使用该资源。Android 2.2之前,系统没有内置一项机制来处理这个问题,这在某些情况下也许会带来不好的用户体验。例如,当用户正在听音乐时,其他的应用程序由于一些非常重要的事情需要提醒用户,这时用户就可能会因为吵闹的音乐而没法听到该提醒。从Android 2.2开始,平台提供了一种途径让应用程序自己协商对设备音频输出的使用。这项机制称为音频焦点。
            当你的应用程序需要输出音乐或提醒时,你应该总是请求音频焦点。一旦它拥有焦点,它就可以随意地使用声音输出,但是它必须随时监听焦点的改变情况。如果应用程序被通知到它已经失去了音频焦点,它就应该将声音关掉或者调低至一个安静的水平;此时,只有在再次得到焦点后,它才可以恢复正常的播放。
            音频焦点本质上是合作性质的。也就是说,我们希望应用程序遵从音频焦点的指示,但是系统并不会强制执行这项规则。如果一个应用程序在失去音频焦点后仍想大声播放音乐,系统并不会做任何事情来阻止它。但是,这会带来非常差的用户体验,用户更可能会去卸载这种粗鲁的应用。
            为了请求音频焦点,你必须调用AudioManager类的requestAudioFocus()方法,就像下面示例所展示的那样:
    AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
    int result = audioManager.requestAudioFocus(this, AudioManager.STREAM_MUSIC,
        AudioManager.AUDIOFOCUS_GAIN);
    
    if (result != AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
        // could not get audio focus.
    }
            requestAudioFcous()方法的第一个参数是一个AudioManager.OnAudioFocusChangeListener回调对象,任何时刻如果音频焦点发生变化,它的onAudioFocusChange()方法就会被调用。因此,你应该在你的service和Activity中实现这个接口。例如:
    class MyService extends Service
                    implements AudioManager.OnAudioFocusChangeListener {
        // ....
        public void onAudioFocusChange(int focusChange) {
            // Do something based on focus change...
        }
    }
            参数focusChange会告诉你音频焦点发生了怎样的改变,它可以是下面值中的某一个:
    • AUDIOFOCUS_GAIN:你获取到了音频焦点。
    • AUDIOFOCUS_LOSS:长时间内,你失去了音频焦点。你必须停止所有音频播放。因为长时间内你都可能不会有音频焦点,这将会是一个你尽可能清理资源的好地方。例如,这时你应该释放MediaPlayer。
    • AUDIO_LOSS_TRANSIENT:你只是暂时失去了音频焦点,在很短时间内你会重新获取到它。你必须停止所有音频播放,但是你可以保持你的资源,因为短时间内你可能将会重新得到音频焦点。
    • AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:你暂时失去了音频焦点,但允许你继续安静地播放音频(低音量),而不是彻底关掉。
            这是一个实现该接口的例子:
    public void onAudioFocusChange(int focusChange) {
        switch (focusChange) {
            case AudioManager.AUDIOFOCUS_GAIN:
                // resume playback
                if (mMediaPlayer == null) initMediaPlayer();
                else if (!mMediaPlayer.isPlaying()) mMediaPlayer.start();
                mMediaPlayer.setVolume(1.0f, 1.0f);
                break;
    
            case AudioManager.AUDIOFOCUS_LOSS:
                // Lost focus for an unbounded amount of time: stop playback and release media player
                if (mMediaPlayer.isPlaying()) mMediaPlayer.stop();
                mMediaPlayer.release();
                mMediaPlayer = null;
                break;
    
            case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
                // Lost focus for a short time, but we have to stop
                // playback. We don't release the media player because playback
                // is likely to resume
                if (mMediaPlayer.isPlaying()) mMediaPlayer.pause();
                break;
    
            case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
                // Lost focus for a short time, but it's ok to keep playing
                // at an attenuated level
                if (mMediaPlayer.isPlaying()) mMediaPlayer.setVolume(0.1f, 0.1f);
                break;
        }
    }
            请记住,音频焦点的API只在API 8(Android 2.2)及更高版本中提供。所以如果你想支持原先老版本的Android,如果有的话,你应该采用那些允许你使用这项特性的向后兼容的策略;否则,那就只能让步。
            你可以通过反射来调用音频焦点相关的方法,或者在单独的类中(例如AudioFocusHelper)实现所有音频焦点的特性,来实现这种向后兼容。下面是这种类的一个例子:
    public class AudioFocusHelper implements AudioManager.OnAudioFocusChangeListener {
        AudioManager mAudioManager;
    
        // other fields here, you'll probably hold a reference to an interface
        // that you can use to communicate the focus changes to your Service
    
        public AudioFocusHelper(Context ctx, /* other arguments here */) {
            mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
            // ...
        }
    
        public boolean requestFocus() {
            return AudioManager.AUDIOFOCUS_REQUEST_GRANTED ==
                mAudioManager.requestAudioFocus(mContext, AudioManager.STREAM_MUSIC,
                AudioManager.AUDIOFOCUS_GAIN);
        }
    
        public boolean abandonFocus() {
            return AudioManager.AUDIOFOCUS_REQUEST_GRANTED ==
                mAudioManager.abandonAudioFocus(this);
        }
    
        @Override
        public void onAudioFocusChange(int focusChange) {
            // let your service know about the focus change
        }
    }
            只有当检测到系统运行在API 8及以上版本时,你才可以创建一个AudioFocusHelper类的实例。例如:
    if (android.os.Build.VERSION.SDK_INT >= 8) {
        mAudioFocusHelper = new AudioFocusHelper(getApplicationContext(), this);
    } else {
        mAudioFocusHelper = null;
    }

    执行清理操作


            正如之前提到的,一个MediaPlayer对象会消耗大量重要的系统资源;所以你只应该在需要的时候才持有它,当你用它完成任务后就调用release()方法。显示调用这个清理方法,而不依赖系统的垃圾回收机制,是非常重要的。因为垃圾回收器也许会在一段时间后才去回收那些可被回收的MediaPlayer,而且垃圾回收器只关心内存的需要,它并不 关心其他媒体相关资源是否充足。所以,在你使用Service的例子中,你应该总是重写onDestory()方法,以确保你释放MediaPlayer对象:
    public class MyService extends Service {
       MediaPlayer mMediaPlayer;
       // ...
    
       @Override
       public void onDestroy() {
           if (mMediaPlayer != null) mMediaPlayer.release();
       }
    }
            除了在服务在被停止时进行释放,你应该时常寻找其他的时机去释放你的MediaPlayer。例如,如果你在一段较长的时间内都不会播放媒体资源(例如,在失去了音频焦点之后),你就应该明确地释放存在的MediaPlayer,并在之后再次创建它。另一方面,如果你只是在非常短的时间内停止播放,你就大概可以继续持有你的MediaPlayer,以避免再次创建和准备它的系统开销。

    处理AUDIO_BECOMING_NOISY Intent


            许多写得好的播放音频的应用在有一个会导致音频变吵闹(通过外置扬声器输出)的事件发生时,都会自动停止当前播放。例如,一位用户正在使用头戴式耳机听音乐,如果此时耳机意外地与设备断开连接,这种情况就可能会发生。然而,这种行为并不会自动产生。如果你没有实现这项特性,音频就会从设备的外置扬声器播出,这也许与并不是用户想要的。
            你可通过处理ACTION_AUDIO_BECOMING_NOISY Intent来确保你的app在这种情况下会停止播放音乐,你可以将下面的内容添加到你的清单文件中来注册你的广播接收器:
    <receiver android:name=".MusicIntentReceiver">
       <intent-filter>
          <action android:name="android.media.AUDIO_BECOMING_NOISY" />
       </intent-filter>
    </receiver>
            这里为该Intent注册了MusicIntentReceiver类作为广播接收器。并且你应该实现这个类:
    public class MusicIntentReceiver extends android.content.BroadcastReceiver {
       @Override
       public void onReceive(Context ctx, Intent intent) {
          if (intent.getAction().equals(
                        android.media.AudioManager.ACTION_AUDIO_BECOMING_NOISY)) {
              // signal your service to stop playback
              // (via an Intent, for instance)
          }
       }
    }

    从Content Resolver获取媒体


            在媒体播放应用中,另一个可能有用的特性就是获取用户设备上存在的音乐的能力。你可以通过查询跟外置媒体相关的ContentResolve来完成它:
    ContentResolver contentResolver = getContentResolver();
    Uri uri = android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
    Cursor cursor = contentResolver.query(uri, null, null, null, null);
    if (cursor == null) {
        // query failed, handle error.
    } else if (!cursor.moveToFirst()) {
        // no media on the device
    } else {
        int titleColumn = cursor.getColumnIndex(android.provider.MediaStore.Audio.Media.TITLE);
        int idColumn = cursor.getColumnIndex(android.provider.MediaStore.Audio.Media._ID);
        do {
           long thisId = cursor.getLong(idColumn);
           String thisTitle = cursor.getString(titleColumn);
           // ...process entry...
        } while (cursor.moveToNext());
    }
            为了在MediaPlayer中使用它,你可以这样做:
    long id = /* retrieve it from somewhere */;
    Uri contentUri = ContentUris.withAppendedId(
            android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, id);
    
    mMediaPlayer = new MediaPlayer();
    mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
    mMediaPlayer.setDataSource(getApplicationContext(), contentUri);
    
    // ...prepare and start...

    PS:翻译如有不妥、歧义的地方,欢迎提出,我会改正,谢谢!

    展开全文
  • Playback.PlaybackSettings Introduction

    千次阅读 2012-11-27 16:21:23
    In aprevious post, Abhishek had talked about the Record... and Playback Engine in VSTT 2010. The Coded UI Test feature in VSTT 2010 also uses this engine to playback UIactions. In this post, i will de

    In aprevious post, Abhishek had talked about the Record and Playback Engine in VSTT 2010. The Coded UI Test feature in VSTT 2010 also uses this engine to playback UIactions.  In this post, i will describe the various settings for Playbackand how you can modify them to improve the resilience of your Coded UI Tests.Playback is configured by modifying the fields in Playback.PlaybackSettingsclass.

     

    1. Continue on Error

    Whenyou are recording a Coded UI test on a login page, the “Auto Completepasswords” popup may have appeared.

    Whenyou playback actions on the login page, this dialog will *not* come up. So theaction that you performed will cause an error. To improve test resilience, theRecord & Playback engine automatically marks this action as “Continue onError”.  When the test is being played back and the error occurs, theengine will continue on to the next action. Specific actions (IE popups,implicit Hovers) when performed by the user are tagged by the engine as“Continue on Error”.

     

    InCoded UI Test, you have the flexibility to turn on “Continue on Error” for anyaction. This is done by the following code snippet.

    Playback.PlaybackSettings.ContinueOnError= true;

    Rememberto turn this flag to false after the section where there are potentialfailures.  Otherwise the engine will ignore all errors and your test willreturn incorrect results. By default this flag is set to false in Coded UITest.

     

    2. Match Exacthierarchy

    TheRecord and Playback Engine uses a hierarchical structure to locatecontrols.  The Yes button in the dialog above is identified as

    Tolocate YesButton during playback, the engine will search forAutoCompletePasswordWindow, then for YesWindow in it, and finally YesButton inYesWindow.

    Sometimesapplication may change so that the hierarchy gets modified. Record and Playbackengine attempts to locate the control, in such cases, by skipping theintermediate elements in the hierarchy. Thus in the example, if it is unable tolocate YesWindow, it will search for YesButton directly underAutoCompletePasswordWindow and all its children.  This behavior can becontrolled by the “Match Exact Hierarchy” setting. This is done by thefollowing code snippet.

    Playback.PlaybackSettings.MatchExactHierarchy= true;

    Ifthe flag is set to true, every control is the hierarchy will be searched inorder. Any failure will result in failure to locate the control.

    Bydefault, this flag is set to false. Note that this may sometimes lead to falsepositives i.e an unintended control may be identified. In such cases, you willhave to change this setting.

     

    3. Search inminimized windows

    TheRecord and Playback Engine searches for controls even inside minimized windows.The minimized window is restored and actions performed on the control insideit.

    Youhave the ability to turn this feature off i.e. prevent the engine from lookingat minimized windows.  This is done by the following code snippet.

    Playback.PlaybackSettings.SearchInMinimizedWindows= false;

     

    4. Smart Match

    TheRecord and Playback Engine identifies controls on the user interface by itssearch properties.  e.g:- The standard calculator window is identified asbelow.

     

    SearchProperties[WinProperties.Window.ControlType]= ControlType.Window.Name;

    SearchProperties[WinProperties.Window.Name]= "Calculator"; 
    SearchProperties[WinProperties.Window.ClassName] = "CalcFrame";

    Someof the search properties may change over time. Record and Playback engine usesa Smart Match algorithm to identify controls if they cannot be located usingthe exact properties. The smart match algorithm uses heuristics and attempts tolocate the control using variations on the search properties.

    Youcan control when Smart Match should be applied. By default Smart Match isapplied for Top Level Windows and all controls. You can turn off Smart matchusing the following code snippet.

    Playback.PlaybackSettings.SmartMatchOptions= SmartMatchOptions.None;

    Thedefault settings (Smart match top level windows and controls) is optimal for aresilient coded UI test. But sometimes it may lead to false positives and thenyou will have to modify this setting.

     

    5. Wait For ReadyLevel

    TheRecord and Playback engine ensures that each UI control is ready to be actedupon before performing any action.  The smart “Wait For Ready” algorithm significantly improves the resilience of your Coded UI Test. Now you don’t need to add the annoying Sleep statements whenever a UI Controlis busy and not ready to receive input. By default, the engine checks the UIThread (foreground thread) to determine if a control is ready.

     

    Youcan turn off Wait For Ready completely by the following code snippet.

    Playback.PlaybackSettings.WaitForReadyLevel= WaitForReadyLevel.Disabled;

     

    Alternatelyyou may want to wait for all threads including background threads. This may berequired if the application is making asynchronous calls that results in UIchanges.  You can do this by the following code snippet.

    Playback.PlaybackSettings.WaitForReadyLevel= WaitForReadyLevel.AllThreads;

    NOTEthat this setting will slow down the engine and should be carefully used.

     

    6.  Set PropertyVerification

    Aftersetting the property of any UI control, the record and playback engine performsa verification pass to ensure that the set succeeded and the UI control now hasthe value assigned to it.

     

    e.g:- You type the text “MSFT” in the search edit box in Bing. After playing backthis action, the engine reads the text property of the search edit box toensure that this set has succeeded.

     

    Incertain applications, the set property may trigger off some business logicwhich then changes that property itself. In such cases, the verification fails.If your application exhibits such a behavior you can turn of the set propertyverification using the following code snippet.

    Playback.PlaybackSettings.SkipSetPropertyVerification= true;

     

    7.  Fail Fast

    TheRecord and playback engine’s search algorithm has a fail fast logic. i.e. Ifthe engine is reasonably confident that the search will not succeed, it willreturn with a failure. This ensures that you are not waiting for a non-existentcontrol for 2 mins (the default search timeout).

     

    Sometimesyou may want to disable fail fast. Typically, you do this along with increasingyour search timeout. You are confidant that the UI control will becomeavailable within a specified duration  (which is longer than the searchtimeout) and you want the engine to wait for that duration.  You can dothis by using the following code snippet.

    Playback.PlaybackSettings.ShouldSearchFailFast= false;

     

    8. Misc

    Otherplayback settings which can be modified include

    a. Delay Between Actions: How long should the engine wait before performing twosuccessive actions? By default, 100 ms.

    b. Search timeout – How long should the engine attempt to locate a control? Bydefault, 2 mins.

    c. Wait for Ready Timeout – How long should the engine continue waiting for acontrol to be ready?  By Default, 60s

    d.Think Time multiplier – For slow machines, assign a high multiple so that therecorded think time is scaled up to handle slower application responses.

    e.Send Keys As ScanCode - By default, the engine sends keys to the applicationunder test as Unicode. But in certain cases, it may need to send keys asscancode. Sending Unicode to such applications will result in failure

     

    NOTE:The Test runner tool in VSTT 2010 also uses the Record and Playback Engine. Youcan configure the playback settings described above in Test runner tool from

    a.mtlm.exe.config – located in %VSINSTALLDIR%\Common7\IDE

    b. Microsoft Test & Lab Manager, navigate toLab Center –> Test Settings , open the applicable Test Settings, select Dataand Diagnostics section and click on the Configure button next to Action Logand Action Recording. In the Advanced section of the dialog, some of thePlayback settings described above may be configured.
    展开全文
  • Android Audio Playback Mode

    千次阅读 2018-04-12 16:40:21
    常见Playback Mode 常见 FLAG 常见的播放录音线程 Audio HAL 输出流设备 常见Playback Mode 1 Deep buffer Playback:音频文件是在AP侧解码成PCM文件,然后再送到ADSP中处理,音效处理在AP侧或者ADSP中进行。...

    常见Playback Mode

    1 Deep buffer Playback:音频文件是在AP侧解码成PCM文件,然后再送到ADSP中处理,音效处理在AP侧或者ADSP中进行。
    Playback mode in which PCM data is sent to the aDSP, postprocessed, and rendered to output sound device; audio effects can also be applied in the ARM or aDSP.
    FLAG: AUDIO_OUTPUT_FLAG_DEEP_BUFFER

    2 Low Latency Playback : 和Deep buffer Playback方式类似,但是它所分配的buffer更小些,并且在ADSP侧只做很少或者基本不做处理, 主要是播放一些对延迟要求较高的音频,
    Playback mode similar to deep buffer that uses a smaller buffer size and minimal or no
    postprocessing in the aDSP so that the PCM stream is rendered to the output sound
    device
    Use cases – Touchtone, gaming audio
    FLAG:AUDIO_OUTPUT_FLAG_FAST

    3 Offload Playback: 音频解码部分的工作是在ADSP中完成,AP侧只负责把音频数据送到ADSP中,送出去后,AP侧会进行休眠,ADSP中会分配一块较大的buffer去处理此数据,在ADSP中进行解码,音效的处理工作,在ADSP解码器处理完数据之前,它会唤醒AP侧去送下一包数据。
    Playback mode in which a large-sized buffer is sent to the aDSP and the APSS goes to sleep; the aDSP decodes, applies postprocessing effects, and outputs the PCM data to the physical sound device. Before the aDSP decoder input runs out of data, it interrupts the APSS to wake up and send the next set of buffers.
    Examples – MP3, AAC, FLAC 24 bit, 24 bit wav playback
    FLAG:AUDIO_OUTPUT_FLAG_DIRECT,AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD,AUDIO_OUTPUT_FLAG_NON_BLOCKING

    每个平台支持哪几种播放模式,以及个播放模式的标志,支持的格式,声道数,输出设备等信息,是在
    audio_policy.conf文件里配置的。
    

    常见 FLAG

    typedef enum {  
      AUDIO_OUTPUT_FLAG_NONE = 0x0,  
      AUDIO_OUTPUT_FLAG_DIRECT = 0x1,  
      AUDIO_OUTPUT_FLAG_PRIMARY = 0x2,  
      AUDIO_OUTPUT_FLAG_FAST = 0x4,  
      AUDIO_OUTPUT_FLAG_DEEP_BUFFER = 0x8,  
      AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD = 0x10,  
      AUDIO_OUTPUT_FLAG_NON_BLOCKING = 0x20  
    } audio_output_flags_t;  

    AUDIO_OUTPUT_FLAG_DIRECT:不进行软件混音直接交HAL进行处理; Indicates cases that need to bypass AudioFlinger
    AUDIO_OUTPUT_FLAG_PRIMARY:软件解码、软件混音、采样率转换(SRC)基本都不能少;
    AUDIO_OUTPUT_FLAG_FAST:不进行采样率转换(SRC);
    AUDIO_OUTPUT_FLAG_DEEP_BUFFER:经处理后(混音加音效等)交HAL进行处理;
    AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD:编码数据直接交HAL进行处理(往往需要有DSP进行硬解码); Indicates the stream should be offloaded
    AUDIO_OUTPUT_FLAG_NON_BLOCKING – Indicates the writes for this stream are nonblocking

    常见的播放录音线程

    android/frameworks/av/services/audioflinger/AudioFlinger.cpp

    
    1929  sp<AudioFlinger::ThreadBase> AudioFlinger::openOutput_l(audio_module_handle_t module,
    1930                                                              audio_io_handle_t *output,
    1931                                                              audio_config_t *config,
    1932                                                              audio_devices_t devices,
    1933                                                              const String8& address,
    1934                                                              audio_output_flags_t flags)
    1935  {
          ..........
                 sp<PlaybackThread> thread;
    1995              if (flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) {
    1996                  thread = new OffloadThread(this, outputStream, *output, devices, mSystemReady);
    1997                  ALOGV("openOutput_l() created offload output: ID %d thread %p",
    1998                        *output, thread.get());
    1999              } else if ((flags & AUDIO_OUTPUT_FLAG_DIRECT)
    2000                      || !isValidPcmSinkFormat(config->format)
    2001                      || !isValidPcmSinkChannelMask(config->channel_mask)) {
    2002                  thread = new DirectOutputThread(this, outputStream, *output, devices, mSystemReady);
    2003                  ALOGV("openOutput_l() created direct output: ID %d thread %p",
    2004                        *output, thread.get());
    2005              } else {
    2006                  thread = new MixerThread(this, outputStream, *output, devices, mSystemReady);
    2007                  ALOGV("openOutput_l() created mixer output: ID %d thread %p",
    2008                        *output, thread.get());
    2009              }
    2010              mPlaybackThreads.add(*output, thread);
    2011              return thread;

    这里写图片描述

    RecordThread
    RecordThread : public ThreadBase, public AudioBufferProvider
    用于录音的线程。

    PlaybackThread:
    class PlaybackThread : public ThreadBase
    用于播放的线程

    MixerThread
    MixerThread : public PlaybackThread
    用于混音的线程,注意是从PlaybackThread派生下来的。负责处理标识为 AUDIO_OUTPUT_FLAG_PRIMARY、AUDIO_OUTPUT_FLAG_FAST、AUDIO_OUTPUT_FLAG_DEEP_BUFFER 的音频流,MixerThread 可以把多个音轨的数据混音后再输出

    DirectoutputThread
    DirectOutputThread : public PlaybackThread
    直接输出线程,DIRECT_OUTPUT最终和这个线程有关。负责处理标识为 AUDIO_OUTPUT_FLAG_DIRECT 的音频流,这种音频流数据不需要软件混音,直接输出到音频设备

    OffloadThread
    classOffloadThread : publicDirectOutputThread {

    DuplicatingThread
    DuplicatingThread : public MixerThread
    复制线程,而且从混音线程中派生

    Audio HAL 输出流设备

    Audio HAL 中,我们通常看到如下 4 种输出流设备,分别对应着不同的播放场景:

    primary_out:主输出流设备,用于铃声类声音输出,对应着标识为 AUDIO_OUTPUT_FLAG_PRIMARY 的音频流和一个 MixerThread 回放线程实例

    low_latency:低延迟输出流设备,用于按键音、游戏背景音等对时延要求高的声音输出,对应着标识为 AUDIO_OUTPUT_FLAG_FAST 的音频流和一个 MixerThread 回放线程实例

    deep_buffer:音乐音轨输出流设备,用于音乐等对时延要求不高的声音输出,对应着标识为 AUDIO_OUTPUT_FLAG_DEEP_BUFFER 的音频流和一个 MixerThread 回放线程实例

    compress_offload:硬解输出流设备,用于需要硬件解码的数据输出,对应着标识为 AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD

    PlaybackThread 与输出流设备的关系:PlaybackThread 实例与输出流设备是一一对应的,比方说 OffloadThread 只会将音频数据输出到 compress_offload 设备中,MixerThread(with FastMixer) 只会将音频数据输出到 low_latency 设备中。
    下图简单描述 AudioTrack、PlaybackThread、输出流设备三者的对应关系:

    这里写图片描述

    系统启动时,就已经打开 primary_out、low_latency、deep_buffer 这三种输出流设备,并创建对应的 MixerThread 了;而此时 DirectOutputThread 与 OffloadThread 不会被创建,直到标识为 AUDIO_OUTPUT_FLAG_DIRECT/AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD 的音频流需要输出时,才开始创建 DirectOutputThread/OffloadThread 和打开 direct_out/compress_offload 设备。

    展开全文
  • Vuforia Video PlayBack

    2020-07-30 23:30:14
    Vuforia Video PlayBack
  • playback视频播放器

    2020-07-17 17:51:37
    playback视频播放器,可播放车载监视器视频。
  • 为了让每个人都能享受这一便利,Adobe已经发布了一款免费视频播放器,其名称为Flash Media Playback视频播放器。 作为最佳视频播放器,Flash Media Playback能够在你需要的时候方便地在线免费找到它。 你可以通过...

    与世界分享视频的最快和最简便的方法是将其放置于因特网。 为了使得大家能够观看视频,视频播放器是必不可少的。 为了让每个人都能享受这一便利,Adobe已经发布了一款免费视频播放器,其名称为Flash Media Playback视频播放器。 作为最佳视频播放器,Flash Media Playback能够在你需要的时候方便地在线免费找到它。 你可以通过添加少量的代码即可在任何web页面使用这一播放器。 本文描述了如何使用Flash Media Playback视频播放器方便地发布视频,并且给出了可用的功能强大选项的概述。

    Flash Media Playback是一款优秀的视频播放器,它适用于博客、小型商务活动、企业网站以及需要使用简单解决方案以提供卓越的、基于web的视频体验的任何人。 Flash Media Playback可以处理与连接视频源相关的复杂问题,并且为用户提供高质量的视频播放效果。 下面是一个利用Flash Media Playback 视频播放器播放的视频范例。


    要求

    为了最大程度地利用本教程,你需要准备下列软件和文件:Flash Media Playback 视频播放器

    Flash Media Playback video player

    Web 文件

    • 上载至web服务器的视频文件 (FLV)
    • 上载至web服务器的web页面,它包含播放器嵌入代码<0}

    Dreamweaver CS5 (optional)

    Prerequisite knowledge

    要求具有使用HTML的经验并且了解基本HTML概念。

    使用Flash Media Playback视频播放器

    如果希望将Flash Media Playback视频播放器集成至你的web页面,你只需将播放器嵌入代码添加至该HTML页面即可。 当访问者在浏览器中加载该web页面时,Flash Media Playback将会自动在该页面显示你的视频播放器。

    共有两种方式创建必需的嵌入代码,以便能够使用Flash Media Playback。

    • Flash Media Playback Setup页面
    • 人工编辑嵌入代码

    Flash Media Playback Setup页面

    如需复制该嵌入代码,请访问Flash Media Playback Setup页面:osmf.org/configurator/fmp/。 Flash Media Playback Setup页面 (参见图1) 包含左右两个主要部分。 使用左边的表格输入视频的值:视频源地址和各种自定义设置。 页面的右边包含一个预看播放器和预看嵌入代码。 输入相应值,然后点击Preview以生成合适的嵌入代码。

    Flash Media Playback setup screen

    图1. Flash Media Playback Setup屏幕

    该表格包含两个必需设置的字段:

    • 视频源URL (链接至视频文件)
    • 播放器尺寸(宽度和高度)

    Flash Media Playback还支持其它许多可配置参数。 然而,仅仅上面列出的值是必需的,其它参数是可选的或可以使用默认值填充。 只要你提供播放器的视频URL和尺寸,即可以生成正确的嵌入代码。

    在Flash Media Playback Setup页面的上部显示两个标签:

    • Player (默认选择)
    • Advanced

    如需了解关于这些选项的更多信息,参见下列文档:

    人工编辑嵌入代码

    如果你熟悉HTML代码,你可以人工编辑Flash Media Playback嵌入代码,而无需从Flash Media Playback Setup页面复制该代码。 你可以使用任意文本编辑器更新该嵌入代码。 如果需要,你可以先复制一些现有的嵌入代码,然后对其进行编辑;你也可以从头手工输入嵌入代码。

    注:如果手工编写的嵌入代码由于输入错误而包含差错,则播放器不能加载并且视频也不能播放。 由于代码差错难于解决,因此只有你拥有能够发现和排除HTML代码故障的经验,才推荐使用人工编辑方式。 当进行人工编辑代码时,像Adobe Dreamweaver CS5等HTML编辑器是非常有用的工具。

    Flash Media Playback支持

    除了Flash Media Playback的全套文档之外,Adobe还提供了一个支持论坛。 Flash Media Playback用户能够访问这些资源以便获取问题解答并且学习最佳实践方法。 请访问Flash Media Playback论坛以便参与社区活动和提出与Flash Media Playback相关的问题。

    Flash Media Playback没有包含的高级视频播放器选项

    Flash Media Playback是一个极具创造性的视频播放器解决方案。 它非常易于实现并且支持各种定制方式以便改变播放器的外观。 Strobe Media Playback(SMP) 是另一个你值得一试的解决方案。

    Flash Media Playback和Strobe Media Playback本质上是相同的-它们均支持相同的配置和植皮方法。 然而,Flash Media Playback不包含下列两个功能,而在使用Strobe Media Playback时,这两个功能是可用的:

    • 在任何web服务器上自由托管播放器
    • 访问播放器源代码

    尽管Strobe Media Playback允许你在任何web服务器上托管播放器,但该功能带来一个限制:不能使用Flash Player高速缓存功能。 当任何访问者首次加载一个包含Flash Media Playback的web页面,Flash Media Playback将首先被下载,然后存储于计算机的Flash Player 高速缓存器(使用一个特殊的、带有SWZ文件扩展名的签名文件)。 从此以后,当访问者访问其它使用Flash Media Playback的页面时,Flash Media Playback加载非常快速,因为它已经安装于计算机之中。 由于使用了Flash Player快速缓存功能,使用Flash Media Playback首次观看视频的速度要比使用Strobe Media Playback更快。

    由于Strobe Media Playback是一个开源项目,并且该源代码可以公开获得,因此许多具有丰富经验的ActionScript编程人员的机构能够对该代码进行扩展和以各种方法定制其播放器,而这些方法在使用Adobe提供的标准Flash Media Playback播放器时是无法获得的。

    对于需要更多定制功能的视频和媒体播放器,开发人员可以充分利用功能强大的开源媒体框架(Open Source Media Framework (OSMF))。 Flash Media Playback和Strobe Media Playback均构建于OSMF之上。 OSMF仍在不断演化,并且一旦OSMF获得新的功能,它们将会同时包含于Flash Media Playback和Strobe Media Playback的未来版本。

    如需了解关于OSMF的更多信息,请访问 OSMF.org。 你也可以阅读我的文章:Open Source Media Framework: Introduction and Overview.

    Adobe Creative Suite 5 应用程序包含许多用于在web页面中显示视频的附加选项。 例如,Adobe Flash Professional CS5包含一个易于使用的视频播放组件,其名称为FLVPlayback,并且Dreamweaver CS5提供一个非常有用的用户界面,以便在HTML页面中插入FLV视频文件。 关于这些选项的更多信息,请参阅下列文章:

    此外,也可以参考 Video Technology CenterVideo Learning Guide for Flash 以便获得关于准备、编码和在线发布视频内容的更多信息。

    作者简介

    provenWebVideo.comGreg Hamer是provenWebVideo.com的创建者和首席架构师,provenWebVideo.com是一家web和移动应用程序开发和软件设计公司。Greg及其provenWebVideo.com团队专门帮助客户构建高度互动的数据驱动应用程序、实时应用程序以及利用Adobe Flash Platform在web中发布视频的视频播放器。他们专门研究与Flash视频相关的所有事宜,其中包括Flash媒体服务器、Flash 媒体互动服务器、开源媒体框架(Open Source Media Framework (OSMF))以及基于Flash Media Playback 和 Strobe Media Playback的定制视频播放器。Greg是一个撰稿人、各种会议的常规演讲嘉宾以及Adobe认证教师 (Adobe Certified Instructor) (Flash, Flex, Flash Video, OSMF, FMS, FMIS, ActionScript, ColdFusion和 Java)。


    展开全文
  • 如下错误: 一般是找不到APE文件导致的。解决方法如下: 1、打开APE文件,对一下路径修改即可。  
  • ALSA调试总结

    千次阅读 2012-05-02 15:45:26
    刚刚解决了一个播放不出声音的问题,这里总结一下,在TI平台上调试ALSA的一些方法和步骤。 平台ALSA信息 ls /dev/snd/ controlC0 controlC1 pcmC0D0c pcmC0D0p pcmC0D10p pcmC0D11c ...pcmC0D15p
  • videojs播放m3u8源在firefox中报错问题

    千次阅读 2019-06-26 16:14:08
    视频分割后存阿里oss,设置好...在firefox和360中提示The media playback was aborted due to a corruption problem or because the media used features your browser did not support.。 ffmpeg分割加入-pix_fmt...
  • 花絮随着越来越深入的移动互联网话,普通安防监控行业也随之卷入其中。目前不少行业都开始希望能将区域内监控摄像头实现web端无插件播放。可以在Windows浏览器、手机浏览器、微信内实时直播观看。...
  • Vuforia新版本中的视频播放——VideoPlayback

    千次阅读 热门讨论 2016-08-16 20:13:24
    最近看到网上大多数视频播放教程都是5.0.X版本的,但是由于高通后来的新版本中VideoPlayback移除了ScenceManager和VideoPlaybackAppManager.cs和VideoPlaybackUIEvenHandler.cs的脚本,导致很多人都实现不了播放,...
  • The Coded UI Test is running in Single Thread Apartment (STA) mode of COM. In this mode, all the playback calls should happen from the TestMethod thread only and UITestControl should not b
  • Android系统audio框架中主要有三种播放模式:low latency playback、deep buffer playback和compressed offload playback。 a)low latency playback:用于按键音、游戏背景音等对时延要求高的声音输出。音频文件是在...
  • 句法: playback_terminators=123456789*0# | any | none 允许您设置哪些DTMF音调,如果在播放文件期间或在mod_dptools:play_and_detect_speech期间按下,将终止播放。默认终止符是*(星号)。将收集未指定为终结符...
  • Android | Vuforia 播放视频

    千次阅读 2015-02-20 00:15:06
    1 下载Video PlayBack Sample https://developer.vuforia.com/resources/sample-apps/video-playback-sample-app2 解压将文件夹放到\vuforia-sdk-android\samples目录下3.从eclipse中打开project4.更改Target数据 ...
  • alsa 音频路径的问题:

    千次阅读 2012-12-26 10:16:00
    alsa 音频路径的问题: ...这里个驱动文件中定义了很多widget和control,alsa在playback或record的时候,sound/soc/soc-dapm.c中的dapm_power_widgets函数会根据“配置情况”打开相应的widget,搭建一个完整的音
  • snd_kcontrol_new名称中的SOURCE字段

    千次阅读 2013-12-17 20:41:56
    前些日子写了一篇snd_kcontrol探究,该文主要从内核源码出发简单讲述一下kcontrol接口的始末。这几天因为要在Android里面添加一些音频控制接口,配合alsa_amixer scontents分析,对此有了更深的体会,记录于此。...
  • 百度地图车辆运动轨迹

    万次阅读 多人点赞 2018-08-25 17:00:44
    先看效果: bolg地址:http://blog.csdn.net/adsdassadfasdfasdf/article/details/7549787       下面是代码: 页面代码: &lt;!DOCTYPE html PUBLIC "-//W3C//DTD ...
  • Broadcom Nexus学习(三):Audio Decoder

    千次阅读 2011-05-09 16:20:00
    先前介绍了Graphics以及AudioPlayback方面的概念,今天介绍AudioDecoder.先从Interface层面看看AudioDecoder思路:要播放本地文件(例如:本地MP3文件),需要的Interface互联路径如下: Audio源可以是同轴电缆传出...
1 2 3 4 5 ... 20
收藏数 20,346
精华内容 8,138
关键字:

playback