【问题标题】:AudioTrack playing with inconsistent speed on different devicesAudioTrack 在不同设备上的播放速度不一致
【发布时间】:2014-09-06 18:10:21
【问题描述】:

我目前正在与AudioTrack 合作。我正在加载一个 mp3 文件并播放它。但是,根据设备的不同,音乐会以一半的速率或正常速率播放。

我的代码:

AudioTrack track= new AudioTrack( AudioManager.STREAM_MUSIC,
    sampleRate,
    AudioFormat.CHANNEL_CONFIGURATION_MONO,
    AudioFormat.ENCODING_PCM_16BIT,
    initBuffer,
    AudioTrack.MODE_STREAM);

sampleRateAudioFormat返回的采样率,initBufferAudioTrack.getMinBufferSize()的缓冲区大小。

我已尝试更改采样率,但没有任何区别。缓冲区大小也没有影响。

事实上,切换到CHANNEL_CONFIGURATION_STEREO 确实使音乐在慢速设备上以正常速度播放,但它也使运行良好的设备以正常速度的两倍播放。我的问题是我希望所有设备都以正常速度播放。

有什么建议吗?

我已经阅读了这个帖子:Android AudioTrack slow playback,但它并没有告诉我如何找出哪些设备应该以单声道或立体声播放。

正常速度的设备:Urbano 4.2.2、Galaxy S4 4.3

设备速度减半、Galaxy S4 4.2.2、Experia Z 4.2.2

顺便说一句,我不能使用MediaPlayer 进行播放。 AudioTrack 包含在自定义播放器中,我需要在提取音频数据时编写它。 MediaPlayer 不会成功。

谢谢。

【问题讨论】:

  • 如果您还没有,订阅andraudio 并在那里询问可能会受益。
  • 谢谢!我也去看看

标签: android audiotrack


【解决方案1】:

我在尝试使用 MediaCodec 解码单声道文件时遇到了这种情况。在某些设备上,编解码器会输出立体声流,而在其他设备上会输出单声道。在设置音轨时,我使用了 MediaExtractor 返回的媒体格式,它是单声道的。在编解码器会产生立体声流的设备上,音轨将被输入两倍的样本。解决办法是从MediaCodec监听MediaFormatChanged事件,调整AudioTrack的MediaFormat。

【讨论】:

    【解决方案2】:

    试试这个:

    track.setPlaybackRate(88200);
    track.play();
    

    它应该以正常速度播放

    【讨论】:

    • 抱歉,我现在无法在设备上进行测试,但它似乎不起作用。改变播放速率确实会改变速度,但不会改变我想要的方式。我的问题是不同的设备将以不同的速率播放。为什么 88200 能让我在所有设备上获得正确的速度?
    • 88200 提供了更高的硬件延迟。
    【解决方案3】:

    AudioTrack 只允许 PCM 音频数据,你不能直接播放带有 AudioTrack 的 mp3,你必须将你的 mp3 转换为 PCM 或使用其他东西(例如 MediaPlayer)而不是 AudioTrack。

    【讨论】:

    • 对不起,我忘了说,我在阅读之前已经在转换文件了。
    【解决方案4】:

    我终于解决了我的问题。不是最好的解决方法,但至少可以。

    对于那些感兴趣的人,我正在阅读BufferInfo 的大小并根据它来决定我应该播放的播放速率。基本上,当播放速度很慢时,大小是正常速度播放的两倍。只是猜测,但MediaCodec 可能会复制立体声配置的数据。

    【讨论】:

      【解决方案5】:

      这个有点棘手,但您可以使用 adbALSA 来执行此操作。
      Android 内部使用ALSA

      你的设备应该有ALSA,试试:

      root@user:/$ adb shell cat /proc/asound/version
      Advanced Linux Sound Architecture Driver Version 1.0.25.
      

      看看Reading ALSA Device names
      每个设备卡片的细分)都有一个capture和一个playback组件。

      例如/proc/asound/card0/pcm1p/proc/asound/card0/pcm1p,其中卡是0,设备是1 pcm1p 是您的回放,pcm1c 是捕获(用于录制)。

      1. 使用adb访问您的设备:

        root@user:/$ adb shell
        shell@android:/$:  
        
      2. 识别您的设备:

        所以你看/proc/asound/pcm会给你一个很长的列表。

        shell@android:/$: cat /proc/asound/pcm                                     
        00-00: MultiMedia1 (*) :  : playback 1 : capture 1
        00-01: MultiMedia2 (*) :  : playback 1 : capture 1
        00-02: CS-Voice (*) :  : playback 1 : capture 1
        

        从上面我发现00-00: MultiMedia1 (*)card0device0 用于多媒体播放。

      3. 获取播放参数:

        播放使用标准音乐播放器应用程序加载的 mp3 文件。
        正在播放歌曲时。​​
        card0device0(p - 播放)和subdevice0发出以下命令

        shell@android:/$: cat /proc/asound/card0/pcm0p/sub0/hw_params              
        access: RW_INTERLEAVED
        format: S16_LE
        subformat: STD
        channels: 2
        rate: 44100 (44100/1)
        period_size: 1920
        buffer_size: 3840
        

        所以在调用AudioTrack track= new AudioTrack(...); 时尝试使用相同的值 上述值仅在设备处于打开状态(播放一些音频)时可见。

        如果您将此发送到错误的设备(例如 pcm1p),您将看到以下内容:

        shell@android:/$: cat /proc/asound/card0/pcm1p/sub0/hw_params    
        closed
        

      注意
      第 1 步不需要手机 root,How to Setup ADB

      替代方案

      1. 您是否尝试过来自heregetChannelConfiguration()getChannelCount() 等AudioTrack API - 只是询问。
      2. 您是否尝试过查看 MP3 文件属性,元数据包含有关音频参数的信息。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-11-16
        相关资源
        最近更新 更多