Compare commits
2 Commits
295bd18719
...
5a6fa242dd
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5a6fa242dd | ||
|
|
64573e29ef |
83
README.md
83
README.md
@@ -1,3 +1,82 @@
|
|||||||
# computer_craft_video_play
|
|
||||||
|
|
||||||
一个用于cc:t 和 Tom's Peripherals 播放视频的程序
|
这是一个专为 **ComputerCraft (CC: Tweaked)** 设计的高性能视频播放器客户端。它利用 **Tom's Peripherals** 外设进行硬件加速渲染,结合远程服务器转码,实现了在 Minecraft 中流畅播放网络视频的功能。
|
||||||
|
|
||||||
|
## ✨ 主要功能
|
||||||
|
|
||||||
|
* **在线转码**:直接输入视频 URL(如 `.mp4` 链接),服务器自动提取帧和音频。
|
||||||
|
* **硬件加速**:利用 `tm_gpu` 外设进行高效的图像解码和绘制。
|
||||||
|
* **音频同步**:支持立体声音频播放(需要扬声器外设),并带有自动追帧/跳帧逻辑以保持音画同步。
|
||||||
|
* **异步缓冲**:使用多线程(协程)并发下载技术,边播边下,极大减少卡顿。
|
||||||
|
* **断点重试**:内置自动重试机制,应对网络波动。
|
||||||
|
* **性能监控**:提供 Debug 模式,实时显示 FPS、渲染耗时和缓冲状态。
|
||||||
|
* **快速重播**:播放结束后生成 Task ID,1小时内可直接凭 ID 再次播放,无需重新转码。
|
||||||
|
|
||||||
|
## 🛠️ 环境要求
|
||||||
|
|
||||||
|
在运行此程序之前,请确保你的游戏环境满足以下条件:
|
||||||
|
|
||||||
|
1. **Mod 要求**:
|
||||||
|
* CC: Tweaked >= 1.105.0
|
||||||
|
* Tom's Peripherals
|
||||||
|
2. **硬件搭建**:
|
||||||
|
* **高级电脑**(金电脑)。
|
||||||
|
* **TM GPU**:连接到电脑(名为 `tm_gpu_0` 或自动搜索)。
|
||||||
|
* **显示器**:连接到 GPU 的显示器。
|
||||||
|
* **扬声器 (Speaker)**:用于播放音频(程序依赖 `speakerlib.lua`)。
|
||||||
|
|
||||||
|
## 📥 安装
|
||||||
|
|
||||||
|
```bash
|
||||||
|
wget https://git.liulikeji.cn/xingluo/computer_craft_video_play/raw/branch/main/play.lua
|
||||||
|
```
|
||||||
|
|
||||||
|
*注:程序首次运行时会自动检查并下载依赖库 `speakerlib.lua`*
|
||||||
|
|
||||||
|
## 🚀 使用方法
|
||||||
|
|
||||||
|
### 1. 播放新视频
|
||||||
|
直接在命令行后跟视频的网络链接地址:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
player https://example.com/video.mp4
|
||||||
|
```
|
||||||
|
|
||||||
|
程序将发送请求到服务器,等待转码后自动开始播放。
|
||||||
|
|
||||||
|
### 2. 通过 ID 重播
|
||||||
|
如果视频在过去一小时内播放过,可以使用任务 ID 直接播放,跳过转码等待:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
player 20116713
|
||||||
|
```
|
||||||
|
*(注:ID 会在视频播放结束后显示在屏幕上)*
|
||||||
|
|
||||||
|
### 3. Debug 调试模式
|
||||||
|
在 URL 或 ID 后添加 `debug` 参数,可在屏幕左上角显示实时性能数据:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
player https://example.com/video.mp4 debug
|
||||||
|
```
|
||||||
|
|
||||||
|
**Debug 信息说明:**
|
||||||
|
* `100/5000`: 当前帧/总帧数
|
||||||
|
* `Avg:20(50ms)`: 平均 FPS(平均每帧耗时)
|
||||||
|
* `Low:15(66ms)`: 最低 FPS(当前秒内最大单帧耗时)
|
||||||
|
|
||||||
|
## ⚙️ 技术细节
|
||||||
|
|
||||||
|
* **API 服务端**:默认连接至 `https://newgmapi.liulikeji.cn`。 服务器项目`https://git.liulikeji.cn/xingluo/GMapiServer`
|
||||||
|
* **分辨率**:程序会自动将 GPU 设置为 `64x` 分辨率模式,并请求服务器将视频缩放至 GPU 的实际宽高 (`w, h`)。
|
||||||
|
* **帧率**:目标帧率为 **20 FPS**(Minecraft 逻辑刻速度)只能是此大小。
|
||||||
|
* **缓存机制**:
|
||||||
|
* **预加载**:播放前预先下载前 20 秒(约 400 帧)的数据。
|
||||||
|
* **动态缓冲**:播放过程中,后台协程会持续预取后续大约 20 秒的帧数据包。
|
||||||
|
* **数据格式**:使用定制的 `FramePack` 二进制格式批量传输帧数据,减少 HTTP 请求开销。
|
||||||
|
|
||||||
|
## ❓ 常见问题
|
||||||
|
|
||||||
|
**Q: 画面很流畅,但声音卡顿/不同步?**
|
||||||
|
A: 这是 CC 扬声器的常见限制。程序内置了追帧逻辑,如果画面落后音频超过 3 帧,会自动跳帧追赶。如果服务器 TPS 过低,可能会导致音频本身播放缓慢。
|
||||||
|
|
||||||
|
**Q: 如何获取任务 ID?**
|
||||||
|
A: 视频播放完毕后,控制台会输出:`The ID for playing the video is XXXXX`。
|
||||||
|
|||||||
9
play.lua
9
play.lua
@@ -188,10 +188,10 @@ end
|
|||||||
-- 分批下载(每批 50 帧)
|
-- 分批下载(每批 50 帧)
|
||||||
local BATCH_SIZE = 20
|
local BATCH_SIZE = 20
|
||||||
-- local totalFrames = #videoInfo.frame_urls
|
-- local totalFrames = #videoInfo.frame_urls
|
||||||
local totalFrames = videoInfo.fps * 20 -- 仅下载前10秒以节省时间
|
local totalFrames = videoInfo.fps * 20 -- 仅下载前20秒以节省时间
|
||||||
local allFrameData = {}
|
local allFrameData = {}
|
||||||
|
|
||||||
-- 第一步:构建所有需要下载的批次(仅前10秒)
|
-- 第一步:构建所有需要下载的批次(仅前20秒)
|
||||||
local initBatches = {}
|
local initBatches = {}
|
||||||
for startIdx = 1, totalFrames, BATCH_SIZE do
|
for startIdx = 1, totalFrames, BATCH_SIZE do
|
||||||
local endIdx = math.min(startIdx + BATCH_SIZE - 1, totalFrames)
|
local endIdx = math.min(startIdx + BATCH_SIZE - 1, totalFrames)
|
||||||
@@ -257,7 +257,7 @@ until _G.audio_ready
|
|||||||
local starttime1 = os.clock()
|
local starttime1 = os.clock()
|
||||||
|
|
||||||
|
|
||||||
-- 播放前已缓存 10 秒
|
-- 播放前已缓存 20 秒
|
||||||
local totalFramesToPlay = #videoInfo.frame_urls
|
local totalFramesToPlay = #videoInfo.frame_urls
|
||||||
|
|
||||||
-- 标志:是否还在播放
|
-- 标志:是否还在播放
|
||||||
@@ -415,9 +415,10 @@ local function renderVideo()
|
|||||||
|
|
||||||
local data = allFrameData[frameIndex]
|
local data = allFrameData[frameIndex]
|
||||||
|
|
||||||
-- === 如果 data 存在才进行解码和渲染 ===
|
-- === 如果 data 存在才进行解码和渲染 否则跳帧 ===
|
||||||
if data then
|
if data then
|
||||||
-- 将字符串转换为字节表
|
-- 将字符串转换为字节表
|
||||||
|
-- 感谢来自 https://center.mcmod.cn/1288558/ 提供高性能解码方案
|
||||||
local imgBin = { data:byte(1, #data) }
|
local imgBin = { data:byte(1, #data) }
|
||||||
data = nil
|
data = nil
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user