13. 摄像头与特殊场景

13.摄像头与特殊场景

scrcpy 的摄像头镜像功能是一个很有意思的特性,它让我们能够直接把 Android 设备的摄像头作为视频源,而不是屏幕。这在很多场景下都派得上用场,比如想把手机摄像头当作电脑摄像头用,或者需要录制一些特殊的视频内容。不过这个功能有个硬性要求:设备必须是 Android 12 或更高版本。如果系统版本不达标,那下面的内容就只能先收藏着了。

要使用摄像头镜像,最基本的命令很简单,就是把视频源从默认的 display 改成 camera:

scrcpy --video-source=camera

执行这条命令后,scrcpy 会尝试打开设备的第一个可用摄像头,并且把画面显示在电脑上。这时候你可能会注意到,音频也自动变成了麦克风输入。这是因为 scrcpy 在摄像头模式下会智能切换音频源,默认行为相当于同时加了 --audio-source=mic 参数。如果想自己控制音频源,可以显式指定:

scrcpy --video-source=display  # 默认音频源是 output(设备输出音频)
scrcpy --video-source=camera   # 默认音频源是 mic(麦克风)
scrcpy --video-source=display --audio-source=mic    # 强制使用屏幕+麦克风组合
scrcpy --video-source=camera --audio-source=output  # 强制使用摄像头+设备音频输出组合

如果不需要音频,直接禁用掉也是个不错的选择,特别是单纯想录制视频画面的时候:

scrcpy --video-source=camera --no-audio
scrcpy --video-source=camera --no-audio --record=file.mp4  # 录制时禁用音频

有时候我们可能想录制音频但不想实时播放,可以用 --no-audio-playback 参数:

scrcpy --video-source=camera --no-audio-playback --record=file.mp4

摄像头列表与选择

在实际使用中,设备上往往不止一个摄像头。现在的手机通常有前置、后置,有些还支持外接 USB 摄像头。这时候就需要先搞清楚到底有哪些摄像头可用。scrcpy 提供了专门的命令来列出摄像头信息:

scrcpy --list-cameras
scrcpy --list-camera-sizes

第一条命令会显示摄像头的 ID 和基本信息,第二条会更详细地列出每个摄像头支持的分辨率和帧率。不过这里有个需要注意的地方:这些列出来的尺寸和帧率是系统声明的值,不一定完全准确。有些设备会声明一些实际上并不支持的参数,而有些设备则支持一些没有声明的参数。所以实际使用时可能需要多试几次。

假设我们已经知道了摄像头的 ID,就可以通过 --camera-id 参数来指定使用哪个摄像头:

scrcpy --video-source=camera --camera-id=0

如果不想记 ID,也可以用更直观的方式选择。scrcpy 支持按摄像头位置自动选择:

scrcpy --video-source=camera                           # 使用第一个可用的摄像头
scrcpy --video-source=camera --camera-facing=front     # 使用第一个前置摄像头
scrcpy --video-source=camera --camera-facing=back      # 使用第一个后置摄像头
scrcpy --video-source=camera --camera-facing=external  # 使用第一个外接摄像头

这里有个规则需要记住:如果同时指定了 --camera-id 和 --camera-facing,scrcpy 会报错,因为 ID 已经唯一确定了摄像头,再指定朝向就矛盾了:

scrcpy --video-source=camera --camera-id=0 --camera-facing=front  # 错误!

分辨率与帧率配置

选定了摄像头之后,下一步就是设置合适的分辨率和帧率。这两个参数对画质和性能影响很大,需要根据实际情况权衡。

最直接的方式是显式指定分辨率:

scrcpy --video-source=camera --camera-size=1920x1080

这个尺寸不一定要出现在 --list-camera-sizes 的列表里。有些设备的摄像头支持任意分辨率,即使没声明也能用。比如你可以试试一些奇怪的分辨率:

scrcpy --video-source=camera --camera-size=1840x444

如果不想自己指定具体尺寸,可以让 scrcpy 自动选择。这时候可以用约束条件来指导选择过程。主要有两种方式:

第一种是使用 -m 或 --max-size 参数限制最大尺寸。这个参数在屏幕镜像时是用来缩放画面的,但在摄像头模式下,它是用来选择源分辨率的:

scrcpy --video-source=camera -m1920  # 选择宽度不超过 1920 的最大可用分辨率

第二种是指定宽高比,用 --camera-ar 参数。这个参数支持多种写法:

scrcpy --video-source=camera --camera-ar=4:3          # 4:3 宽高比
scrcpy --video-source=camera --camera-ar=1.6          # 1.6:1 宽高比
scrcpy --video-source=camera --camera-ar=sensor       # 使用摄像头传感器的原生宽高比

宽高比匹配时有 10% 的容错范围,所以不用太精确。也可以组合使用多个约束条件:

scrcpy --video-source=camera -m1920 --camera-ar=16:9  # 宽度不超过 1920 且最接近 16:9 的分辨率

如果什么都不指定,scrcpy 会选择宽度最大的分辨率,以及对应的最大高度。

这里有个重要的限制:如果显式指定了 --camera-size,就不能再用 -m 或 --camera-ar 了,因为尺寸已经确定,再设置约束条件就会产生冲突:

scrcpy --video-source=camera --camera-size=1920x1080 -m3000  # 错误!

帧率的设置相对简单,默认情况下摄像头会以 Android 的默认帧率(通常是 30fps)捕获。要改变帧率,使用 --camera-fps 参数:

scrcpy --video-source=camera --camera-fps=60

这个帧率设置会尽量匹配,但最终效果还是取决于摄像头硬件的支持情况。

有时候我们可能需要旋转视频画面,特别是摄像头安装方向不对的时候。可以用 --orientation 参数:

scrcpy --video-source=camera --camera-size=1920x1080 --orientation=90

这个旋转是在客户端进行的,不会影响摄像头的实际捕获方向。

高速捕捉模式

对于需要捕捉高速运动的场景,比如运动分析、科学实验或者慢动作回放,普通的帧率可能不够用。Android 的相机 API 提供了高速捕捉模式,支持 120fps、240fps 甚至更高的帧率。

要启用高速模式,需要满足两个条件:一是分辨率必须在支持高速模式的列表中,二是帧率也要在支持范围内。可以用 --list-camera-sizes 查看哪些分辨率和帧率组合支持高速模式。

启用高速模式的命令很简单,只要帧率设置得足够高,scrcpy 会自动启用高速模式:

scrcpy --video-source=camera --camera-size=1920x1080 --camera-fps=240

如果想显式指定使用高速模式,可以加上 --camera-high-speed 参数:

scrcpy --video-source=camera --camera-size=1280x720 --camera-high-speed --camera-fps=120

需要注意的是,高速模式对光线要求很高,在暗光环境下画面可能会很暗或者出现噪点。而且高速模式通常会限制自动对焦和自动曝光的功能,所以使用时要有心理准备。

这里分享一个小技巧:所有摄像头相关的选项都以 --camera- 开头,如果你的 shell 支持花括号展开(比如 bash 和 zsh),可以写得简洁一些:

scrcpy --video-source=camera --camera-{facing=back,ar=16:9,high-speed,fps=120}

这行命令会被展开成:

scrcpy --video-source=camera --camera-facing=back --camera-ar=16:9 --camera-high-speed --camera-fps=120

这样写不仅简洁,而且便于修改和复用。

Webcam 应用场景

摄像头镜像最吸引人的应用场景之一,就是把 Android 设备变成电脑的外接摄像头。这在 Linux 系统上通过 V4L2(Video4Linux2)接口实现特别方便。

基本思路是:把 scrcpy 捕获的摄像头视频流输出到一个虚拟的 V4L2 设备节点,这样其他应用程序(比如 Zoom、OBS、Zoom)就可以像使用普通 USB 摄像头一样使用 Android 设备的摄像头了。

首先,需要加载 v4l2loopback 内核模块来创建虚拟摄像头设备:

sudo modprobe v4l2loopback video_nr=2  # 创建 /dev/video2 设备

然后使用 scrcpy 的 --v4l2-sink 参数把视频流输出到这个设备:

scrcpy --video-source=camera --camera-size=1920x1080 --camera-facing=front --v4l2-sink=/dev/video2 --no-playback

这里有几个关键点需要注意:

  1. --v4l2-sink 指定了虚拟摄像头设备的路径,通常是 /dev/videoX,X 是一个数字
  2. --no-playback 表示不在 scrcpy 窗口中显示画面,因为我们要把画面输出到虚拟摄像头
  3. 可以同时指定 --camera-facing 来选择前置或后置摄像头
  4. 分辨率要根据实际需求设置,常见的 1920x1080 或 1280x720 兼容性最好

设置完成后,打开 Zoom 或 OBS,在摄像头列表里就能看到 /dev/video2 这个设备了。选择它,Android 摄像头的画面就会出现在视频会议或直播软件中。

这个方案有几个明显的优势:首先,手机摄像头的画质通常比笔记本自带的摄像头好很多;其次,手机摄像头的角度更灵活,可以随意调整位置;最后,如果手机支持 4K 或者高速拍摄,还能获得更好的视频效果。

不过也有局限性:目前这个功能主要在 Linux 上支持得比较好,Windows 和 macOS 上可能需要额外的工具或者配置。而且延迟问题也需要考虑,虽然 scrcpy 本身延迟很低,但经过 V4L2 转发后可能会有一些增加。

除了视频会议,这个技术还有很多创意用法。比如可以把手机摄像头用作直播的特写机位,或者用于机器视觉项目的原型开发。甚至可以把多部手机的摄像头组合起来,实现多机位拍摄效果。

音频同步处理

在摄像头模式下,音频处理有一些特殊之处。前面提到过,默认情况下音频源会自动切换到麦克风,这个设计很贴心,因为使用摄像头时通常需要录制环境声音或者语音讲解。

但有时候我们可能需要不同的音频配置。比如在做产品演示时,可能想同时录制摄像头画面和设备的内部音频(比如播放的视频声音)。这时候就需要手动指定音频源:

scrcpy --video-source=camera --audio-source=output  # 摄像头画面 + 设备音频输出

或者在做一些不需要音频的场景,比如监控或者机器视觉应用,可以完全禁用音频:

scrcpy --video-source=camera --no-audio

录制时的音频处理也值得注意。默认情况下,录制会包含当前播放的音频。如果用了 --no-audio-playback,音频会被录制但不会实时播放,这在一些专业录制场景中很有用,可以避免音频回授或者干扰。

音频同步是另一个需要考虑的问题。摄像头捕获和音频捕获是两条独立的流水线,虽然 scrcpy 会尽量保证它们的同步,但在一些极端情况下(比如系统负载很高或者使用了复杂的滤镜处理),可能会出现音画不同步的现象。如果发现同步问题,可以尝试降低分辨率或帧率,减少系统负担。

对于需要精确同步的专业应用,建议在后期制作中手动调整同步。可以在录制开始时做一个明显的视觉和听觉标记(比如拍手或者闪光灯),这样后期对齐起来会容易很多。

在实际使用中,我发现摄像头模式的音频质量很大程度上取决于设备的麦克风硬件和系统音频处理。有些设备会有明显的降噪或者回声消除处理,这在通话场景是好的,但在需要真实环境音的场景可能就不合适了。目前 scrcpy 还不能控制这些底层音频处理参数,如果需要更专业的音频控制,可能需要配合其他音频采集工具使用。

摄像头镜像功能为 scrcpy 打开了很多新的应用场景。从简单的视频录制到复杂的直播推流,从日常的视频会议到专业的机器视觉开发,这个功能都展现出了很大的潜力。虽然目前在某些平台(特别是 Windows 和 macOS)上的支持还不够完善,但在 Linux 上已经相当成熟了。

下一章我们将探讨窗口管理与界面定制,看看如何更好地控制 scrcpy 的显示界面,包括窗口位置、大小、边框样式等细节。这些技巧对于需要精细控制显示效果的用户来说会非常有用。