5. 音频处理与录制

5.音频处理与录制

scrcpy 的音频处理功能在 Android 11 及以上版本中才真正可用,这一点需要特别注意。如果设备还停留在 Android 10 或更早版本,音频转发功能会自动禁用,整个投屏过程将只有画面没有声音。对于 Android 11 用户,启动时需要确保屏幕处于解锁状态,scrcpy 会弹出一个假窗口来获取音频捕获权限。到了 Android 12,这一切都变得简单,开箱即用,无需额外操作。

音频功能默认是开启的,但如果捕获失败,scrcpy 会自动降级为纯视频模式,不会直接报错退出。这种设计很贴心,毕竟音频只是增强体验,不是核心功能。不过,如果某些场景下必须要求音频,可以加上 --require-audio 参数,这样音频捕获失败时整个程序会终止,而不是静默降级。

音频源与编解码配置

音频源的选择

默认情况下,scrcpy 捕获的是设备的所有音频输出,技术上称为 REMOTE_SUBMIX。这种模式下,设备自身的扬声器会自动静音,避免在电脑端和手机上同时播放造成回声。但有时候,我们可能想捕获不同的音频源,比如麦克风输入或者通话音频。

scrcpy 提供了丰富的音频源选项,通过 --audio-source 参数指定:

scrcpy --audio-source=mic

这个命令会捕获麦克风输入,适合把 Android 设备当作电脑的外接麦克风使用。除了 mic,还有多个专业级选项:

  • output:默认选项,捕获所有音频输出并禁用设备播放
  • playback:仅捕获应用播放的音频,Android 13+ 支持,且应用可以选择不被捕获
  • mic-unprocessed:捕获未经过处理的原始麦克风信号
  • mic-camcorder:针对视频录制优化的麦克风模式
  • mic-voice-recognition:针对语音识别优化的麦克风模式
  • mic-voice-communication:针对语音通话优化,支持回声消除和自动增益
  • voice-call:捕获通话双向音频
  • voice-call-uplink:仅捕获通话上行音频(自己的声音)
  • voice-call-downlink:仅捕获通话下行音频(对方的声音)
  • voice-performance:同时捕获麦克风和设备播放,适合卡拉 OK 场景

每个选项背后都对应 Android 系统的 MediaRecorder.AudioSource 常量,scrcpy 只是把这些专业功能暴露给了命令行。选择哪个源取决于具体场景:做语音笔记用 mic,录游戏解说可能用 voice-performance,而调试通话质量则需要 voice-call 系列选项。

Android 13 引入了一个很实用的功能:音频复制(duplication)。使用 --audio-source=playback 配合 --audio-dup 参数,可以让音频同时在设备和电脑上播放:

scrcpy --audio-dup

这个命令会自动选择 playback 作为音频源,并保持设备端的音频输出。不过要注意,Android 13 以下版本不支持这个功能,而且应用有权选择不被捕获,所以某些应用可能无法复制音频。

编解码器的选择

音频编码格式直接影响音质和延迟。scrcpy 默认使用 Opus 编码,这是目前最先进的低延迟音频编码器,特别适合实时传输。但如果设备比较老旧,可能不支持 Opus 编码,这时会遇到错误提示:"Failed to initialize audio/opus, error 0xfffffffe"。

遇到这种情况,切换到 AAC 编码通常能解决问题:

scrcpy --audio-codec=aac

scrcpy 支持四种音频编解码器:

  • opus:默认选项,低延迟高效率,适合实时场景
  • aac:兼容性最好,几乎所有设备都支持
  • flac:无损压缩,适合对音质要求极高的录制场景
  • raw:未压缩的 PCM 16-bit 小端格式,体积最大但处理最简单

选择编解码器时需要权衡:Opus 延迟最低但兼容性稍差,AAC 兼容性最好但音质略逊,FLAC 音质完美但文件体积大,RAW 格式最简单但带宽消耗惊人。对于普通投屏,默认的 Opus 已经足够。如果要长期录制音乐或播客,FLAC 可能是更好的选择。

FLAC 编码还支持压缩级别调整,范围从 0 到 8,数字越大压缩率越高,但编码耗时也越长:

scrcpy --audio-codec=flac --audio-codec-options=flac-compression-level=8

这个命令将 FLAC 压缩级别设为最高,生成的文件会更小,但会消耗更多 CPU 资源。大多数情况下,默认的压缩级别就能提供很好的平衡。

编码器的选择

每个编解码器在设备上可能对应多个编码器实现。比如 Opus 编码,可能有硬件加速的 c2.android.opus.encoder,也可能有软件实现的 omx.google.opus.encoder。不同编码器的性能和兼容性差异很大。

查看设备上所有可用的音频编码器:

scrcpy --list-encoders

输出会列出视频和音频编码器,找到 audio 部分就能看到所有选项。如果某个编码器工作不正常,可以手动指定另一个:

scrcpy --audio-codec=opus --audio-encoder='c2.android.opus.encoder'

这个命令强制使用特定的 Opus 编码器。通常不需要手动指定,让 scrcpy 自动选择即可。但在某些设备上,自动选择的编码器可能存在 bug,这时手动切换就能解决问题。

比特率的设置

音频比特率决定音质和带宽消耗。默认值是 128Kbps,这个码率下的 AAC 音质已经接近无损,Opus 则能提供更好的音质。如果网络带宽有限,可以适当降低比特率:

scrcpy --audio-bit-rate=64K

比特率可以写成 64K 或 64000 两种形式,效果相同。需要注意的是,RAW 编解码器不支持比特率设置,因为它是未压缩的 PCM 数据,比特率由采样率和位深固定计算得出。

降低比特率能有效减少网络传输压力,但也会损失音质。64Kbps 的 Opus 音质依然不错,适合网络环境较差的场景。如果带宽充足,保持默认值或适当提高到 192Kbps 能获得更好的听感。

缓冲区与延迟优化

缓冲机制的本质

音频缓冲是实时传输中不可避免的技术环节。缓冲区太小,网络抖动会导致音频断断续续;缓冲区太大,延迟会变得明显,声音和画面不同步。scrcpy 默认设置 50ms 的音频缓冲区,这个值在延迟和稳定性之间取得了不错的平衡。

调整缓冲区大小的参数是 --audio-buffer:

scrcpy --audio-buffer=40

这个命令将缓冲区减少到 40ms,延迟更低,但对网络稳定性要求更高。如果 Wi-Fi 信号不稳定,可能会出现偶尔的破音。相反,增大缓冲区能提升稳定性:

scrcpy --audio-buffer=100

100ms 的缓冲能很好地抵抗网络抖动,适合观看视频场景。在这种场景下,轻微的延迟并不影响体验,流畅性更重要。需要注意的是,这个参数设置的是目标缓冲值,实际运行中可能因为频繁的缓冲区下溢而无法达到这个目标。

对于纯音频场景,比如把手机当作电脑音箱,延迟根本不重要,可以设置更大的缓冲区:

scrcpy --no-video --audio-buffer=200

200ms 的缓冲几乎能消除所有网络抖动带来的破音,音质会非常稳定。因为没有了视频,不用担心音画同步问题,大缓冲只有好处没有坏处。

输出缓冲区的微调

除了传输缓冲区,scrcpy 还有一个音频输出缓冲区,默认只有 5ms。这个缓冲区负责把解码后的音频数据送到声卡。5ms 已经非常小了,通常不需要调整。

但在某些特殊声卡驱动或虚拟音频设备上,可能会听到机器人般的声音或频繁破音。这时可以尝试增大输出缓冲区:

scrcpy --audio-output-buffer=10

这个参数除非遇到特定问题,否则不建议修改。增大输出缓冲区会增加一点点延迟,但可能解决驱动兼容性导致的音质问题。如果音频听起来正常,完全不用理会这个参数。

音视频同步的缓冲策略

当同时调整视频和音频缓冲时,保持两者一致有助于同步:

scrcpy --video-buffer=200 --audio-buffer=200

这个配置把视频和音频缓冲都设为 200ms,适合观看电影或录播课程。大缓冲能确保流畅播放,虽然延迟增加,但对于非交互场景完全可接受。如果做的是实时游戏直播,则需要把缓冲调小,比如都设为 30ms,牺牲一点稳定性换取更低的延迟。

纯音频模式应用

仅音频播放的场景

有时候我们并不需要视频画面,只想把手机音频转发到电脑。比如把手机当作无线麦克风,或者只想听手机上的音乐而不想看屏幕。这时可以禁用视频和控制功能:

scrcpy --no-video --no-control

这个命令启动后不会显示视频窗口,也不会转发键盘鼠标操作,只有音频在传输。配合 --no-window 参数,连窗口都不会创建,完全在后台运行:

scrcpy --no-window

--no-window 隐含了 --no-video 和 --no-control,所以单独使用就够了。这种模式适合长期运行,比如把手机作为电脑的外接麦克风。停止时按 Ctrl+C 即可。

音频录制的实用技巧

纯音频模式最常见的用途是录制。比如想录一段手机上的播客或音乐,可以直接在电脑上录制,避免手机内部录音的音质损失:

scrcpy --no-video --no-playback --record=audio.opus

这个命令不播放音频(--no-playback),直接录制到 audio.opus 文件。--no-playback 能节省系统资源,特别适合长时间录制。录制格式根据文件扩展名自动选择,.opus 对应 Opus 编码,.aac 对应 AAC,.flac 对应 FLAC,.wav 对应 RAW。

如果想用手机作为高质量录音笔,捕获麦克风输入:

scrcpy --audio-source=mic --no-video --no-playback --record=voice.flac

这个配置捕获原始麦克风信号,用 FLAC 无损格式保存到电脑,音质远超手机自带的录音应用。因为是无损录制,后期处理空间很大,适合采访、音乐创作等专业场景。

音视频同步处理

同步机制的原理

scrcpy 的音视频同步依赖时间戳。设备端在捕获音视频帧时,会打上精确的时间戳。这些数据传输到电脑后,播放器根据时间戳来同步播放。理论上,只要网络延迟稳定,同步效果就会很好。

但实际使用中,网络抖动会导致音视频到达时间不一致。这时缓冲区的设置就至关重要。如果音频缓冲设为 50ms,视频缓冲设为 200ms,音频会比视频快 150ms,导致明显的音画不同步。

解决方法是保持音视频缓冲一致,或者根据内容类型调整。对于对话类视频,音频更重要,可以稍微减小音频缓冲;对于音乐演出,同步要求极高,必须保持严格一致。

同步问题的排查

如果发现音画不同步,首先检查缓冲区设置:

scrcpy --audio-buffer=50 --video-buffer=50 --print-fps

--print-fps 会显示实时帧率,帮助判断是网络问题还是配置问题。如果帧率稳定但不同步,说明缓冲区设置不当。如果帧率波动很大,说明网络带宽不足,需要降低分辨率或增大缓冲。

另一个常见问题是音频漂移,即开始时同步,但时间越长差距越大。这通常是设备端编码器的问题,可以尝试切换编码器:

scrcpy --audio-encoder='omx.google.aac.encoder'

使用软件编码器虽然 CPU 占用高,但时间戳更精确,能减少漂移问题。

录制参数与格式选择

基础录制命令

scrcpy 的录制功能非常灵活,可以同时录制音视频,也可以只录其中一个流。基础录制命令很简单:

scrcpy --record=video.mp4
scrcpy -r video.mkv

-r 是 --record 的简写。录制时,音视频在设备端编码,在电脑端封装成容器文件。时间戳在设备端生成,所以网络延迟不会影响录制文件的同步质量,只有实时播放时才受影响。

如果只想要视频,不要音频:

scrcpy --no-audio --record=video.mp4

这个配置适合录制游戏画面,后期再配解说。反过来,只录音频也很简单:

scrcpy --no-video --record=audio.opus

纯音频录制支持多种格式,可以根据需要选择编码器:

scrcpy --no-video --audio-codec=aac --record=audio.aac
scrcpy --no-video --audio-codec=flac --record=audio.flac
scrcpy --no-video --audio-codec=raw --record=audio.wav

容器格式的选择

scrcpy 支持多种容器格式,根据文件扩展名自动选择:

  • MP4 家族:.mp4、.m4a、.aac
  • Matroska 家族:.mkv、.mka
  • Opus:.opus
  • FLAC:.flac
  • WAV:.wav

MP4 和 Matroska 是通用容器,支持音视频混流。Opus、FLAC 和 WAV 是纯音频格式。如果文件名没有标准扩展名,可以手动指定格式:

scrcpy --record=file --record-format=mkv

这个命令会创建一个名为 file 的 Matroska 格式文件,不管扩展名是什么。手动指定格式在批量处理或自动化脚本中很有用。

高级录制场景

有时候需要录制但不播放,避免电脑端播放影响性能或造成回声:

scrcpy --no-playback --no-control --record=file.mp4

这个配置完全不播放音视频,只进行录制。配合 --no-window 可以彻底隐藏界面:

scrcpy --no-playback --no-window --record=file.mp4

这种后台录制模式适合长时间监控或自动化测试。停止录制按 Ctrl+C 即可,文件会自动保存完整。

还可以单独禁用音频播放,只播放视频:

scrcpy --record=file.mkv --no-audio-playback

这在录制游戏解说时很有用:电脑端播放游戏画面,但音频只录制不播放,避免和麦克风输入混合。

录制时长控制

录制不一定需要手动停止,可以设置时间限制:

scrcpy --record=file.mkv --time-limit=20

这个命令录制 20 秒后自动停止。--time-limit 不仅限于录制,普通投屏也支持,时间到了会自动断开连接。这在自动化测试中很有用,可以确保测试用例在固定时间内完成。

时间单位是秒,支持小数:

scrcpy --time-limit=1.5  # 1.5秒

对于需要精确控制时长的场景,比如录制短视频素材,这个参数比手动按 Ctrl+C 可靠得多。


音频处理是 scrcpy 的高级功能,需要 Android 11 及以上版本支持。从音频源选择到编解码配置,从缓冲优化到纯音频应用,每个环节都有精细的参数可以调整。默认配置已经能满足大多数场景,但了解这些选项能让我们在特殊需求下游刃有余。无论是把手机当作无线麦克风,还是录制高质量音频素材,scrcpy 都能胜任。

下一章将深入探讨键盘输入的细节,包括 SDK 键盘与物理键盘模拟的区别,以及 UHID 和 AOA 这两种先进技术的对比。键盘输入的精度直接影响使用体验,特别是在游戏和文字处理场景中。