前言
关于如何在局域网内从 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)
(内放声音) 设备名称的方法在此不赘述。
- 查询 dshow 设备
- 桌面画面(纯视频流):
-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
2ffmpeg -f dshow -i audio="Stereo Mix (Realtek High Definition Audio)" ^
-re -f lavfi -i testsrc -vf "drawtext='text=%{localtime\:%c}:box=1" OUTPUT使用测试用视频音频流并嵌入时间字幕:
1
2ffmpeg -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 / 设置 / 隐私 / 麦克风 / 开关
- 打开 Win10 的隐私设置,将麦克风的权限打开:
Only one stream supported in the RTP muxer
- RTP 协议中一个地址只能串流一个流媒体,除非使用
rtp_mpegts
的容器格式可以同时串流视音频。
- RTP 协议中一个地址只能串流一个流媒体,除非使用
直播
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 | ffmpeg -re -f lavfi -i testsrc -f lavfi -i anoisesrc ^ |
本地测试接收串流:
(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 | ffmpeg -re -f lavfi -i testsrc -f lavfi -i anoisesrc ^ |
本地测试接收串流:
1 | ffplay rtp://236.0.0.1:1234 |
iOS
VLC / 网络串流 /
rtp://236.0.0.1:1234
细枝末节
- 可使用任意空闲组播地址,任意空闲端口号。
- 基于
UDP
的RTP
组播直接串流无需等待,因此不太稳定。 - 受 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
流媒体服务器,iOS
从Nginx
服务器拉流。
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 | worker_processes 1; |
常用命令
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 | ffmpeg -re -f lavfi -i testsrc -f lavfi -i anoisesrc ^ |
本地测试接收串流:
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
也可以换成其他名字,使用时保持前后一致即可。 - 相比基于
UDP
的RTP
串流,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 | ffmpeg -re -f lavfi -i testsrc -f lavfi -i anoisesrc ^ |
本地测试接收串流:
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.264
和aac
。不正确的编码格式不会生成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 | ffmpeg -re -f lavfi -i testsrc -f lavfi -i anoisesrc ^ |
本地测试接收串流:
1 | ffplay http://localhost:8080/dash/room.mpd |
iOS
VLC / 网络串流 /
http://192.168.0.1:8080/dash/room.mpd
细枝末节
- 基本与 HLS 串流一致。
直播附笔
一些与正文无关的絮絮叨叨,建议跳过。
- 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 似乎不支持串流到广播地址?)
- VLC 应用对 UDP/RTP 传输的流媒体格式也有要求:
- 关于
VLC
的网络串流
支持的 7 种协议的可行串流方法:- HTTP
- HTTP 文件服务器的媒体文件网址
- HLS/DASH 串流地址
- FFmpeg 内建 HTTP 服务器的点对点串流地址
- RTMP
- FFmpeg 推流至本地 nginx + rtmp 流媒体服务器的串流地址
- FTP
- FTP 文件服务器的媒体文件网址
- UDP/RTP
- FFmpeg 的 RTP 组播串流地址
- RTSP
- 无法只靠 FFmpeg 完成,需要搭建 RTSP 服务器串流。
- MMS
- 不清楚
- HTTP
- 其他流媒体服务器与
ffserver
开源流媒体服务器还有很多选择, 不一定要使用 Nginx + nginx-rtmp-module 作为流媒体服务器。
- FFmpeg 系列以前似乎曾包含 ffserver 程序作为流媒体服务器,支持 RTSP 等协议,不过已经停止开发了。
- nginx for Windows
- 一个团队提供的 Windows 上编译好的 Nginx,也是本文所使用的 Nginx 程序包的来源。
- 不过免费版从很久之前就开始不再包含 rtmp 模块,所以本文中使用的是旧版 Nginx。
- 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
附录
部分相关参考
- FFmpeg Wiki
- RTP、RTSP、SDP、ffserver
- RTP 和 UDP 串流
- RTP Payload Type 相关
- RTP 点对点串流
- RTP 与 MPEG2 Transport Stream
- RTP/RTSP 所使用的 SDP 文件详解
- RTSP 与 ffserver 串流
- Nginx 串流
- rtmp-module 文档
https://github.com/arut/nginx-rtmp-module/wiki/Directives - RTMP
- HLS
- DASH
- rtmp-module 文档
- WMP 串流
http://bbs.wfun.com/thread-819319-1-1.html - iOS VLC 应用
题外话
- 实时与即时
- 串流与流式传输
- 现场直播与直接广播
- 播送与放送
- 双向通话及视频会议