简易建立 Win10 至 iOS 的多媒体无线串流

前言

关于如何在局域网内从 Win10 系统串流至 iOS 系统的一些简易方法的总结。

主要使用 FFmpeg 和 iOS 的 VLC 应用通过常见的流媒体协议实现直播串流,以及其他一些不需使用 FFmpeg 的点播串流方法。

(多媒体串流,指无需下载完整文件就可以播放流媒体。)

写作 primer guide,读作笔记


目录

  • 前言
  • 目录
  • 简介
    • 用途
    • 优点
    • 弊端
    • 环境准备参考
    • FFmpeg 使用示例
  • 直播
    • HTTP 点对点串流
    • UDP/RTP 组播串流
    • RTMP/HLS/DASH 流媒体服务器串流
    • 直播附笔
  • 点播
    • 常见文件服务器
    • DLNA / UPnP 服务器
    • 点播附笔
  • 其他类型
  • 附录
    • 部分相关参考
    • 题外话

简介

用途

  • 局域网网络广播电台/电视台
  • 局域网点唱机/点播机
  • 家庭多媒体中心
  • 将 iOS 设备用作蓝牙/无线音箱
  • 没有实用价值

优点

  • 免费开源软件解压即用,无需安装,无需编译,无需管理员权限。
  • VLC 应用支持后台串流播放。

弊端

  • 串流占用局域网带宽,略微影响其他局域网用户。
  • 需要在命令行进行操作。
  • 延迟 2 s 起步,比不上蓝牙/无线音箱。直播串流时间越长,延迟可能越大。
  • 直播串流地址随局域网 IP 分配而变动,不方便使用。
  • VLC 应用不是专门用作串流音乐的,所以专辑封面等等界面体验较差。
  • 音画质或有损失。

环境准备参考

  • 网络
    • Win10 电脑与 iOS 手机位于同一个局域网内。
    • 一个较为安全的局域网。
  • Win10 系统
    • FFmpeg 程序 (ver.4.1.3)
    • 防火墙相关设置,相关风险自负。
      • 弹出的防火墙窗口中允许程序通信;
      • 或者添加例外规则;
      • 或者暂时禁用防火墙。
    • (如有需要) Nginx 程序包(含 nginx-rtmp-module 模块)
      • 例如:nginx 1.7.11.3 Gryphon.zip
  • iOS 系统
    • VLC 应用 (ver.3.1.9)(或其他同类应用)

FFmpeg 使用示例

关于 FFmpeg 串流/推流时所使用的输入参数的示例,以及可能会遇到的问题。

可选的输入源(INPUT):

  • 测试用输入源(纯视频流):
    -re -f lavfi -i testsrc
  • 测试用噪音源(纯音频流):
    -re -f lavfi -i anoisesrc
  • 立体声混响声卡源(纯音频流):
    -f dshow -i audio="Stereo Mix (Realtek High Definition Audio)"
    • 查询 dshow 设备 立体声混响(Stereo Mix)(内放声音) 设备名称的方法在此不赘述。
  • 桌面画面(纯视频流):
    -f gdigrab -framerate 30 -i desktop
  • 某个视频/音频文件:
    -re -i "video_file_fullpath"

示例

  • 使用测试用输入源(纯视频流):

    1
    ffmpeg -re -f lavfi -i testsrc OUTPUT
  • 使用测试用输入源并嵌入时间字幕(纯视频流):

    1
    ffmpeg -re -f lavfi -i testsrc -vf "drawtext='text=%{localtime\:%c}:box=1" OUTPUT
  • 使用测试用输入源和立体声混响并嵌入时间字幕:

    1
    2
    ffmpeg -f dshow -i audio="Stereo Mix (Realtek High Definition Audio)" ^
    -re -f lavfi -i testsrc -vf "drawtext='text=%{localtime\:%c}:box=1" OUTPUT
  • 使用测试用视频音频流并嵌入时间字幕:

    1
    2
    ffmpeg -re -f lavfi -i testsrc -f lavfi -i anoisesrc ^
    -vf "drawtext='text=%{localtime\:%c}:box=1" OUTPUT

可能的问题或者报错信息:

  • 在 CMD 命令行提示符或者批处理脚本的不同执行环境中对 % 字符的转义:
    • 命令行中无需转义,但脚本中必须替换为 %%
    • 命令行中:
      ffmpeg -re -f lavfi -i testsrc -vf "drawtext='text=%{localtime\:%c}:box=1" OUTPUT
    • 脚本中:
      ffmpeg -re -f lavfi -i testsrc -vf "drawtext='text=%%{localtime\:%%c}:box=1" OUTPUT
  • [Parsed_drawtext_0 @ 0000029542c8c680] Stray % near '%{localtime:%%c}'
    • 同上
  • [dshow @ 0000023cfbff78c0] real-time buffer [Stereo Mix (Realtek High Definition Audio)] [audio input] too full or near too full (63% of size: 3041280 [rtbufsize parameter])! frame dropped!
    • 也许是有什么原因导致编码速度受限,如果不是因为太多无关软件占用 CPU 的情况,那可能是编码器的速度已经到达了极限。
  • 串流的音频卡顿
    • 可能是上面提及的编码速度的原因。
    • 或者使用了类似 -re -f dshow -i audio="Stereo Mix (Realtek High Definition Audio)" 的参数,错误地在 立体声混响 之类的输入源前添加了 -re 参数。单独剔除掉立体声混响输入源前的 -re 即可。
    • 又或者可能是 mpegts 格式串流时容易发生音频流丢包。
  • [dshow @ 062f2780] Could not run graph (sometimes caused by a device already in use by other application) audio=Stereo Mix (Realtek High Definition Audio): I/O error
    • 打开 Win10 的隐私设置,将麦克风的权限打开:
      Win10 / 设置 / 隐私 / 麦克风 / 开关
  • Only one stream supported in the RTP muxer
    • RTP 协议中一个地址只能串流一个流媒体,除非使用 rtp_mpegts 的容器格式可以同时串流视音频。

直播

Win10 上使用 FFmpeg 推流,iOS 上使用 VLC 应用拉流。

  • 直播推流总要占用不少 CPU,CPU 的负荷情况也会影响串流的稳定性。

HTTP 点对点串流

使用 FFmpeg 自带的(实验性)HTTP 服务器点对点串流至 iOS。

Win10

(Win10 监听地址:http://0.0.0.0:8080

1
ffmpeg INPUT -listen 1 -f mpegts http://0.0.0.0:8080

示例:

1
2
ffmpeg -re -f lavfi -i testsrc -f lavfi -i anoisesrc ^
-vf "drawtext='text=%{localtime\:%c}:box=1" -listen 1 -f mpegts http://0.0.0.0:8080

本地测试接收串流:
(Win10 IP 地址:192.168.0.1

1
ffplay http://192.168.0.1:8080

iOS

VLC / 网络串流 / http://192.168.0.1:8080

细枝末节

  • 可使用任意空闲端口号。
  • 基于 TCP 的 FFmpeg HTTP 点对点串流在收到串流请求之前会一直等待,容易塞满缓冲区,所以这种方法不方便用处也不大
  • 串流的容器格式除了 mpegts 也可以是其他例如 flv

UDP/RTP 组播串流

使用 FFmpeg 通过 RTP 协议组播串流至 iOS

  • 即使是使用 WiFi 也没有问题。
  • 是很方便的局域网内一对多串流方法。

Win10

(组播地址:236.0.0.1

1
ffmpeg INPUT -f rtp_mpegts rtp://236.0.0.1:1234

示例:

1
2
ffmpeg -re -f lavfi -i testsrc -f lavfi -i anoisesrc ^
-vf "drawtext='text=%{localtime\:%c}:box=1" -f rtp_mpegts rtp://236.0.0.1:1234

本地测试接收串流:

1
ffplay rtp://236.0.0.1:1234

iOS

VLC / 网络串流 / rtp://236.0.0.1:1234

细枝末节

  • 可使用任意空闲组播地址,任意空闲端口号。
  • 基于 UDPRTP 组播直接串流无需等待,因此不太稳定。
  • 受 RTP 串流所需的 rtp_mpegts 格式所限,串流时音质会有所损失,或者提高 CPU 占用增加音频码率来降低损失:
    ffmpeg -re -f lavfi -i testsrc -f lavfi -i anoisesrc -vf "drawtext='text=%{localtime\:%c}:box=1" -c:a aac -b:a 512k -f rtp_mpegts rtp://236.0.0.1:1234
  • 似乎适合用来串流到后台播放,因为在后台播放被打断的情况也容易在数秒内恢复串流。
  • FFmpeg 应该可以进行 RTP 点对点串流,只是 VLC 应用并不支持以这种方式串流。

RTMP/HLS/DASH 流媒体服务器串流

使用 FFmpeg 推流至本地运行的 Nginx 流媒体服务器,iOSNginx 服务器拉流。

  • Nginx 服务器的 nginx-rtmp-module 模块提供 RTMP/HLS/DASH 三种协议的方式进行一对多串流
    • HLS/DASH 协议的串流方式会不断生成切片文件,虽然默认设置为自动删除,但略麻烦,串流延迟也高,所以不建议选用。
    • 模块还提供网页查看统计信息、录制、控制接口等功能,在此不赘述。
  • 流媒体服务器可以同时接收多个推流、进行多个串流。(虽然用不上)

Nginx 安装配置

Win10 系统上 Nginx + nginx-rtmp-module 服务器的安装配置:

  • 基本安装配置教程数不胜数大同小异,在此不再赘述。
    • 下载 http://nginx-win.ecsds.eu/download/nginx%201.7.11.3%20Gryphon.zip
    • 解压;
    • 完成。
配置示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
worker_processes  1;

error_log logs/error.log info;

events {
worker_connections 1024;
}

rtmp {
server {
listen 1935;

application rtmp {
live on;
record off;
}

application hls {
live on;
hls on;
hls_path temp/hls;
}

application dash {
live on;
dash on;
dash_path temp/dash;
}
}
}

http {
server {
listen 8080;

location / {
root html;
}

location /stat {
rtmp_stat all;
rtmp_stat_stylesheet stat.xsl;
}

location /stat.xsl {
root html;
}

location /hls {
types{
application/vnd.apple.mpegurl m3u8;
video/mp2t ts;
}
alias temp/hls;
expires -1;
add_header Cache-Control no-cache;
add_header Access-Control-Allow-Origin *;
}

location /dash {
root temp;
add_header Cache-Control no-cache;
add_header Access-Control-Allow-Origin *;
}
}
}
常用命令

Nginx 目录下:

  • 启动 Nginx 服务器:start nginx
  • Nginx 命令行参数帮助:nginx -h
  • 查看 Nginx 进程:tasklist|find /n /i "nginx"
  • 关闭 Nginx 服务器:nginx -s quit&taskkill /t /f /fi "imagename eq nginx*"

RTMP 串流

Win10

(RTMP 推流地址:rtmp://localhost/rtmp/room

1
ffmpeg INPUT -f flv rtmp rtmp://localhost/rtmp/room

示例:

1
2
ffmpeg -re -f lavfi -i testsrc -f lavfi -i anoisesrc ^
-vf "drawtext='text=%{localtime\:%c}:box=1" -f flv rtmp://localhost/rtmp/room

本地测试接收串流:

1
ffplay rtmp://localhost/rtmp/room
iOS

(Win10 IP 地址:192.168.0.1

VLC / 网络串流 / rtmp://192.168.0.1/rtmp/room

细枝末节
  • 可在 Nginx 配置文件的 RTMP 配置中使用任意空闲端口号。本例的配置中 RTMP 服务的端口为默认的 1935,因此省略。
  • 串流地址中的 room 也可以换成其他名字,使用时保持前后一致即可。
  • 相比基于 UDPRTP 串流,RTMP 串流要稳定得多,而且 flv 格式还支持立体音混响的无损音质串流,意味着更少的 CPU 占用,例如:
    ffmpeg -f dshow -i audio="Stereo Mix (Realtek High Definition Audio)" -c:a copy -f flv rtmp://localhost/rtmp/room
  • RTMP 推流的视音频编码只要与 flv 容器格式相容就行。
  • 不过如果串流到 iOS 的后台播放被打断的话,似乎不容易恢复播放,需要重新打开串流。
  • 以 flv 格式串流的视频质量不算好,这就需要微调一下 FFmpeg 的推流编码参数了。
  • nginx -s reload 之后,之前正在播放的串流不会被强行中断。

HLS 串流

Win10

(HLS 推流地址:rtmp://localhost/hls/room

1
ffmpeg INPUT -c:v h264 -c:a aac -f flv rtmp://localhost/hls/room

示例:

1
2
ffmpeg -re -f lavfi -i testsrc -f lavfi -i anoisesrc ^
-vf "drawtext='text=%{localtime\:%c}:box=1" -c:v h264 -c:a aac -f flv rtmp://localhost/hls/room

本地测试接收串流:

1
ffplay http://localhost:8080/hls/room.m3u8
iOS

VLC / 网络串流 / http://192.168.0.1:8080/hls/room.m3u8

细枝末节
  • 可在 Nginx 配置文件的 HTTP 配置中使用任意空闲端口号。本例的配置中 HTTP 服务的端口为 8080
  • HLS 推流的视音频编码格式建议为 H.264aac。不正确的编码格式不会生成 m3u8 列表文件串流,不过依然可以用 RTMP 地址串流播放,例如:
    ffplay rtmp://localhost/hls/room

DASH 串流

Win10

(DASH 推流地址:rtmp://localhost/dash/room

1
ffmpeg INPUT -c:v h264 -c:a aac -f flv rtmp://localhost/dash/room

示例:

1
2
ffmpeg -re -f lavfi -i testsrc -f lavfi -i anoisesrc ^
-vf "drawtext='text=%{localtime\:%c}:box=1" -c:v h264 -c:a aac -f flv rtmp://localhost/dash/room

本地测试接收串流:

1
ffplay http://localhost:8080/dash/room.mpd
iOS

VLC / 网络串流 / http://192.168.0.1:8080/dash/room.mpd

细枝末节
  • 基本与 HLS 串流一致。

直播附笔

一些与正文无关的絮絮叨叨,建议跳过。

  1. UDP/RTP 在 WiFi 环境下也能成功串流?

    是的。主要视乎 VLC 应用支持播放什么格式的 UDP/RTP 流媒体(和路由器是否支持),不过 VLC 应用似乎只支持基于 UDP 的 RTP 协议而不支持单纯的 UDP 协议去串流。

    • VLC 应用对 UDP/RTP 传输的流媒体格式也有要求:
      • 似乎只支持 RTP Payload Types(RTP 有效载荷类型)中列出的编码格式。
        串流其他编码格式需要使用 SDP 文件,而 VLC 似乎不支持使用 SDP 文件的方式串流。
      • ffmpeg 推流时必须使用 -f rtp_mpegts 的输出格式才能被 VLC 正确解码串流。

        RTP 似乎只支持一个地址串流一个视频/音频流,而在 RTP Payload Types 中列出的编码格式中似乎只有 MP2T(MPEG-2 transport stream)格式支持同时串流视音频。

        虽然不建议,但在只串流一个视频/音频流的情况下,使用 RTP Payload Types 中列出的编码格式也可以被 VLC 正确解码串流,比如:
        • 0:PCMU :
          ffmpeg -re -f lavfi -i aevalsrc="sin(400*2*PI*t)" -ar 8000 -f mulaw -f rtp rtp://127.0.0.1:1234
        • 10:L16 :
          ffmpeg -f dshow -i audio="Stereo Mix (Realtek High Definition Audio)" -f s16be -c:a pcm_s16be -f rtp rtp://236.0.0.1:1234
    • (RTP 似乎不支持串流到广播地址?)
  2. 关于 VLC网络串流 支持的 7 种协议的可行串流方法:
    • HTTP
      • HTTP 文件服务器的媒体文件网址
      • HLS/DASH 串流地址
      • FFmpeg 内建 HTTP 服务器的点对点串流地址
    • RTMP
      • FFmpeg 推流至本地 nginx + rtmp 流媒体服务器的串流地址
    • FTP
      • FTP 文件服务器的媒体文件网址
    • UDP/RTP
      • FFmpeg 的 RTP 组播串流地址
    • RTSP
      • 无法只靠 FFmpeg 完成,需要搭建 RTSP 服务器串流。
    • MMS
      • 不清楚
  3. 其他流媒体服务器与 ffserver

    开源流媒体服务器还有很多选择, 不一定要使用 Nginx + nginx-rtmp-module 作为流媒体服务器。

    • FFmpeg 系列以前似乎曾包含 ffserver 程序作为流媒体服务器,支持 RTSP 等协议,不过已经停止开发了。
    • nginx for Windows
      • 一个团队提供的 Windows 上编译好的 Nginx,也是本文所使用的 Nginx 程序包的来源。
      • 不过免费版从很久之前就开始不再包含 rtmp 模块,所以本文中使用的是旧版 Nginx。
  4. FFmpeg 以外的选择

    推流工具不仅限于 FFmpeg,比如 OBS。直播姬


点播

常见文件服务器

SMB/FTP 服务器

搭建 SMB 或者 FTP 文件服务器在局域网中共享媒体文件,然后在 VLC 应用的 本地网络 中浏览服务器目录并进行点播串流。

  • 搭建 SMB/FTP 服务器的教程数不胜数,不再赘述。
  • 关于使用 VLC 应用浏览 FTP 服务器时可能出现的乱码问题的解决办法,在此不赘述。

HTTP 服务器

搭建 HTTP 服务器在局域网中共享媒体文件,手动复制文件网址到 VLC 中播放。

  • 各种简易搭建本地 HTTP 服务器的教程技巧软件繁多,不再赘述。

DLNA / UPnP 服务器

更为常见好用的局域网共享媒体方法,就是搭建 DLNA 或者 UPnP 服务器,VLC 应用似乎支持在 本地网络 中自动发现并浏览串流。

  • 搭建 DLNA 或 UPnP 服务器的免费或收费的软件选择众多甚至还有配套 iOS 客户端,不再赘述。
    “UPnP AV media servers”, “stream video smarter”, “The open media solution”, “The Free Software Media System”, …
  • 例如 foobar2000 就可以使用 UPnP/DLNA Renderer, Server, Control Point 插件提供 UPnP 音乐串流。
    VLC 应用虽然可以串流播放,不过使用 iOS 系统上的 foobar2000 应用串流播放体验更好。

点播附笔

同样与正文无关的絮叨。

  • 音乐/音频串流何不用网易云、iTunes、Spotify
  • Win10 自带的 Windows Media Player 不也支持串流吗?

    可以,VLC 应用似乎也支持,但是操作起来有些复杂让人头晕。因为我没串流成功过
    (比如说没找到 停止串流 的按钮或是什么。似乎需要手动禁用 Windows Media Player Network Sharing Service 服务


其他类型

从 Win10 到 iOS 的串流方式其实还有很多,例如:

  • 远程桌面/屏幕共享
    • Chrome Remote Desktop
    • NVIDIA GameStream & Moonlight
  • 游戏串流/遥控游玩
    • Steam & Steam Link
  • 无线投屏/扩展桌面
    • spacedesk

附录

部分相关参考

题外话

  • 实时与即时
  • 串流与流式传输
  • 现场直播与直接广播
  • 播送与放送
  • 双向通话及视频会议
0%