特斯拉如何在行驶过程中通过浏览器观看视频
背景
特斯拉为了驾驶安全,一旦挂入 D 档后,车载浏览器中的所有 <video> 标签都会被强制终止,WebRTC 方案也不可行。
但是,浏览器渲染图片和播放音频是不受限制的。
于是想到一个曲线救国的方案:用 ffmpeg 实时转码视频为 JPEG 图片流,浏览器不断渲染图片,同时单独转码音频流供浏览器播放。
实现思路
1 | 特斯拉浏览器 |
实现效果
核心是 ffmpeg 两路流:
- 视频流:实时转码为 JPEG 帧,浏览器通过
<img>标签不断刷新显示 - 音频流:实时转码为 MP3 格式,浏览器直接播放
项目地址
https://github.com/JoyLau/opencarstream
这个项目 fork 自开源项目 santibacat/opencarstream,我这边做了一些 BUG 修复和对国内 Bilibili 视频站的支持。
核心实现
MJPEG 帧解析
JPEG 图片以 0xFFD8 开头(SOI),以 0xFFD9 结尾(EOI),通过这两个标记从字节流中切分出每一帧:
1 | SOI = b"\xff\xd8" |
音频缓冲
音频数据通过单独的线程持续读取并存入缓冲区,浏览器请求时从缓冲区获取:
1 | def _drain(): |
支持的视频源
| 来源 | 示例 URL |
|---|---|
| YouTube | https://www.youtube.com/watch?v=VIDEO_ID |
| Bilibili | https://www.bilibili.com/video/BVxxx |
| Twitch | https://www.twitch.tv/channelname |
| Twitter/X | https://x.com/user/status/TWEET_ID |
| Pluto TV | 内置频道列表 |
| IPTV | .m3u / .m3u8 播放列表 |
| 本地文件 | 通过 Local Media 标签页 |
我做的改进
相比原项目,主要做了以下改进:
1. Bilibili 视频站支持
- 新增 Bilibili 标签页:在 Web 界面添加独立的 Bilibili 标签页
- 视频搜索功能:支持在界面内直接搜索 Bilibili 视频
- 搜索历史:自动保存搜索历史,最多保留 100 条记录,方便快速访问常看的内容
- 缩略图支持:播放页面显示视频缩略图预览
2. 音视频播放优化
- 防止重复启动 pipeline:添加
_pipeline_started标志,避免同一个流被重复启动 - 进程管理优化:改进 ffmpeg 和 yt-dlp 进程的终止逻辑,确保资源正确释放
- 流停止处理:优化返回按钮和流停止的处理逻辑,避免残留进程
3. UI 改进
- 视频卡片样式:优化视频卡片的样式和结构
- 防盗链处理:添加
<meta name="referrer" content="no-referrer">解决B站图片无法加载的问题