SoundEffect 不会在 android 上播放 WAV 音效

SoundEffect does not play a WAV soundeffect on android

提问人:Ivan Folbort 提问时间:11/17/2023 最后编辑:Abderrahmene Rayene MihoubIvan Folbort 更新时间:11/19/2023 访问量:40

问:

我最近在我的Qt应用程序中添加了对音效回放的支持,并将其移植到android平台。

为了播放我的声音文件,我使用了QML组件,它能够播放我的效果,但对于频繁的声音毫无用处,因此我需要一个更高效的组件,它可以以较小的延迟重播声音效果。MediaPlayer

根据 Qt 的文档,应该是首选,但由于某种原因声音没有播放。SoundEffect

在我的调试状态输出中,我可以看到当被触发时,设置为 ,但随后立即重置为 false。在控制台输出中,我可以看到以下消息:SoundEffect.play()playingtrue

W QtAudioDeviceManager: Built in Earpiece may not work when Wired Headphones are connected
D AudioManager: setMode mode=2 from com.indurad.ioau
I AudioManager: In stopBluetoothSco(), calling application: com.indurad.ioau
I AudioManager: In setBluetoothScoOn(), on: false, calling application: com.indurad.ioau
I AudioManager: In setSpeakerphoneOn(), on: false, calling application: com.indurad.ioau
D om.indurad.ioa: PlayerBase::PlayerBase()
D om.indurad.ioa: TrackPlayerBase::TrackPlayerBase()
I libOpenSLES: android_audioPlayer_realize, channel mask 0x3
I libOpenSLES: android_audioPlayer_realize, create default channel mask 0x3, channels 2
I libOpenSLES: Emulating old channel mask behavior (ignoring positional mask 0x3, using default mask 0x3 based on channel count of 2)
D AudioTrackExtImpl: AudioTrackExtImpl init
D AudioTrack: set() streamType 3, sampleRate 24000, format 0x1, channelMask 0x3, frameCount 0, flags #104, notificationFrames -2, sessionId 1673, transferType 0, uid -1, pid -1 cbf 1
E AudioSystem: invalid attributes { Content type: AUDIO_CONTENT_TYPE_UNKNOWN Usage: AUDIO_USAGE_UNKNOWN Source: AUDIO_SOURCE_DEFAULT Flags: 0x0 Tags:  } when converting to stream
D AudioTrack: createTrack_l(0): AUDIO_OUTPUT_FLAG_FAST denied by server; frameCount 0 -> 968
I AudioTrack: createTrack_l(2091) on outputId(13) : 0x70a15a1400, mCblk = 0x721b6cc000,  mLatency = 88, mAfLatency = 48, frameCount = 968, mSampleRate = 24000, mFlags = 0, mReqFrameCount = 968, mNotificationFramesAct = 480
D ListServiceUtils: mListServiceUtils::init CallingPid 32492
D ListServiceUtils: mListServiceUtils::init this 0x70be56c740
D AudioTrack: setVolume left 0.000 right 0.000 , callingPid 32492
D AudioTrack: start(2091): prior state:STATE_STOPPED output 13 stream 3 session 1673
D om.indurad.ioa: PlayerBase::stop() from IPlayer
D AudioTrack: stop(2091): prior state:STATE_ACTIVE output 13 stream 3 session 1673
D AudioTrack: stop(2091): called with 2400 frames delivered
D AudioTrack: flush(2091): prior state:STATE_STOPPED
D AudioTrack: start(2091): prior state:STATE_FLUSHED output 13 stream 3 session 1673
D om.indurad.ioa: PlayerBase::stop() from IPlayer
D AudioTrack: stop(2091): prior state:STATE_ACTIVE output 13 stream 3 session 1673
D AudioTrack: stop(2091): called with 2400 frames delivered
D AudioTrack: flush(2091): prior state:STATE_STOPPED
D AudioTrack: start(2091): prior state:STATE_FLUSHED output 13 stream 3 session 1673
D om.indurad.ioa: PlayerBase::stop() from IPlayer
D AudioTrack: stop(2091): prior state:STATE_ACTIVE output 13 stream 3 session 1673
D AudioTrack: stop(2091): called with 4328 frames delivered
D AudioTrack: flush(2091): prior state:STATE_STOPPED
D AudioTrack: start(2091): prior state:STATE_FLUSHED output 13 stream 3 session 1673
D om.indurad.ioa: PlayerBase::stop() from IPlayer
D AudioTrack: stop(2091): prior state:STATE_ACTIVE output 13 stream 3 session 1673
D AudioTrack: stop(2091): called with 4328 frames delivered
D AudioTrack: flush(2091): prior state:STATE_STOPPED
D AudioTrack: start(2091): prior state:STATE_FLUSHED output 13 stream 3 session 1673
D om.indurad.ioa: PlayerBase::stop() from IPlayer
D AudioTrack: stop(2091): prior state:STATE_ACTIVE output 13 stream 3 session 1673
D AudioTrack: stop(2091): called with 4320 frames delivered
D AudioTrack: flush(2091): prior state:STATE_STOPPED
D AudioTrack: setVolume left 1.000 right 1.000 , callingPid 32492

消息:

E AudioSystem:无效属性 { 内容类型:AUDIO_CONTENT_TYPE_UNKNOWN 用法:AUDIO_USAGE_UNKNOWN 来源:AUDIO_SOURCE_DEFAULT 标志:0x0 标签:} 转换为流时

让我看到了一些文章,这些文章说音频文件应该在文件系统中提供,而不是在Qt资源系统中提供。

但是,我有点卡住了如何按原样将资产部署到android APK,而不将它们集成为Qt资源系统。

我正在使用:

  • Qt 6.4.2版本
  • CMake 用于构建 android 包。
Android Qt 音频 QML

评论

0赞 Stephen Quan 11/17/2023
如果您将文件转换为 或 .Qt编解码器是有限的,但后两种格式/编解码器更有可能是跨平台的。wavmp3ogg
0赞 Ivan Folbort 11/17/2023
奇怪的是,对于 mp3 和 ogg 格式,声音根本无法播放。我得到的错误是.可能我缺少一些支持 mp3 和 ogg 的 qt 库W ioau : QSoundEffect(qaudio): Error decoding source qrc:/SOFTFS/assets/Lukas-beep.mp3
0赞 musicamante 11/17/2023
QSoundEffect 文档明确指出它仅支持未压缩的格式,因此尝试使用 mp3 或 ogg 文件是行不通的。我一般不习惯 Android 和 MD,不过你检查过有关资产的文档吗?此外,您的文件似乎具有不常见的采样率(24000),这应该不是问题,但永远不要说永远:尝试将其转换为更标准的速率,例如 44.1k 或 48k。
1赞 Ivan Folbort 11/23/2023
@musicamante,感谢您的链接,我一直在寻找这样的东西,以便能够在不将它们添加到 qt 资源的情况下提供资产文件。我玩了一下采样率,并尝试在不同的设备中播放文件,确实有帮助。似乎在Oppo智能手机上播放采样率为44.1kHz<音频文件无法正常工作。将采样率设置为48kHz是最佳结果。
0赞 musicamante 11/23/2023
@IvanFolbort 有趣。所以,我的预感实际上是对的:采样是罪魁祸首。我实际上有点惊讶:我不是 Android 开发人员,但据我所知,它应该能够重新采样“仿射”率(也基于文档)。但这是开放系统的缺点之一:每个人都可以改变任何事情;似乎您的 Oppo 的 Android 版本忽略了重采样,即使它是兼容的速率:根据上述文档,传统速率 (48kHz) 的“半下采样”应该不是问题。还。。。

答:

3赞 Stephen Quan 11/18/2023 #1

[根据@musicamante条评论进行编辑]

在理解文件格式时,您必须意识到格式和内部流编解码器都很重要。

为了演示,我用 和 测试了一堆文件。MediaPlayerSoundEffect

文件格式 Windows
媒体播放器
Android
媒体播放器
Windows
SoundEffect
安卓
音效
.wav pcm_s16le,44100 Hz,立体声,s16,1411 kb/s 是的 是的 是的 是的
.mp3 mp3, 44100 Hz, 立体声, fltp, 206 kb/s 是的 是的
.mp2 mp2, 44100 Hz, 立体声, s16 384 kb/s 是的 是的
.ogg 沃比斯,44100 Hz,立体声,FLTP 是的
.ogg flac,44100 Hz,立体声,s32(24 位),128 kb/s

从上表中可以看出几个结果:

    1. MediaPlayer播放的格式比 .这是可以理解的,因为仅限于未压缩的格式,因此它可以具有较低的延迟。SoundEffectSoundEffect
    1. ogg/vorbis在 Android 上播放,但没有。强调仅支持容器是不够的,您需要注意流编解码器ogg/flac
    1. wav立体声 44100 Hz 在所有测试的平台上都成功播放

我用来准备上述文件的软件是 ,我使用的脚本是:ffmpeg

ffmpeg -y -i test.wav test.mp3
ffmpeg -y -i test.wav test.mp2
ffmpeg -y -i test.wav -acodec libvorbis -vn test_ogg_vorbis.ogg
ffmpeg -y -i test.wav -acodec flac      -vn test_ogg_flac.ogg

评论

1赞 musicamante 11/19/2023
OP 不是在问 MediaPlayer,而是在问 SoundEffect。前者使用底层后端对源进行解码并最终显示/播放结果。此外,[Q]MediaPlayer的功能取决于后端的功能,这可能与操作系统完全无关:例如,Qt可以使用自定义(或修改)的后端构建,从而能够在一个配置上复制一个文件,而不是在另一个配置中,即使使用相同的操作系统。 [Q]SoundEffect是一个原始播放器, 它使用文件源的未压缩数据,然后直接从 QAudioOutput 读取。
1赞 musicamante 11/19/2023
因此,虽然你关于格式和编解码器之间差异的观点是正确的(准确地说,精确的区别应该是关于容器的,并且还要考虑不一致的文件扩展名),但给定的比较与QSoundEffect无关,因为只有第一个文件最终才能工作。请注意:不能绝对保证任何给定的未压缩波形文件始终有效:大多数系统完全能够支持大多数标准数字音频格式(采样率/深度、字节序、音频通道等),但可能仍然无法播放一些。
0赞 musicamante 11/23/2023
如果可以的话,我还需要注意一些。从 Qt 6.5 开始,ffmpeg 是 [Q]MediaPlayer 在所有平台上的默认后端(Yocto 发行版除外,请参阅有关目标平台和后端的文档),这意味着:1.Windows、Linux、macOS(iOS?)和 Android 之间不会有区别;2. 由于 FFmpeg 更加灵活,以前不起作用的格式(如 OGG/FLAC)现在可以播放;3. 有争议的是,由于后端的原因,以前在某些平台或系统上可用的格式(例如,通过 »
0赞 musicamante 11/23/2023
» 在 Windows 上安装额外的编解码器包)可能由于许可证不兼容而不再起作用(请参阅上面链接中的“许可证和归属”部分);4. 未压缩音频的播放能力完全取决于系统,因为声音设备可能具有操作系统(通过“驱动程序”或音响系统提供的功能)可能并不总是修复的局限性:例如,采样频率不兼容,这似乎是 OP 的情况(源文件以不寻常的 24kHz 速率采样);标准费率(44.1 和 48)通常是安全的,通常可用,但是 »
0赞 musicamante 11/23/2023
» 这仍然取决于系统:如果目标是嵌入式设备,它可能会受到音频功能和性能的进一步限制(例如:仅提供 8、16、22.05 和 24kHz 的音频设备,但 CPU 有限,无法承受下采样),这意味着无论如何都不会播放具有更高采样的未压缩音频文件。无论如何,我建议你更新你的答案,指定用于测试的Qt和操作系统(包括特定的Android设备/变体)的版本。