本地 HTTP API
透過 App 內建的 HTTP 服務,查詢播放狀態、推送內容、管理檔案與交換裝置資料。以下按目前程式碼核對,不是 GitHub Pages 網站提供的 API。
先確認連線位址
服務從埠號 9978 依序嘗試到 9998,使用第一個成功啟動的埠。請先啟動 App,依 App 顯示的實際位址連線。
127.0.0.1:9978 換成 App 的區域網路 IP 與埠號。範例中的 example.com 與 192.0.2.10 僅作結構示意。連線測試curl "http://127.0.0.1:9978/device"一般參數可放在 Query String;POST 表單使用 application/x-www-form-urlencoded。中文、URL 與 JSON 字串需 URL 編碼,範例使用 curl 的 --data-urlencode 處理。不要把整包 JSON body 當作一般表單參數。
多數文字回應使用 text/plain,包括內容為 JSON 的 /media、/device 與目錄列表。檔案、圖片、解析頁及代理各有自己的 Content-Type;不能統一假設全部為 application/json。
/action 通常先派送事件或排入主執行緒再回傳 OK;未知指令、缺少必要內容或沒有播放服務,也可能回傳 OK 而未執行。這些端點沒有通用 token 驗證,請只在可信任的區域網路使用,不要直接開放到公網。/action:動作指令
使用 GET 或表單 POST,透過 do 選擇操作。下列參數都屬於同一次請求。
| do | 參數 | 用途 |
|---|---|---|
control | type | 控制目前播放器;可用指令見下表。 |
danmaku | text | 送出一條即時彈幕;需要有效的播放服務與非空文字。 |
refresh | type;依類型加 path 或 json | 重新整理頁面,或推送字幕、彈幕及 Vod 更新。 |
push | url | 把非空 URL 交給 App 推送播放流程。 |
file | path | 開啟裝置上的檔案;不是上傳檔案。 |
search | word | 把非空關鍵字交給 App 搜尋介面。 |
setting | text、name(選填) | 把配置位置或設定文字交給設定流程;text 不可為空。 |
cast | config、device、history | 三者均為 JSON 物件字串,交給 App 投放事件處理。 |
sync | type、mode、force 等 | 交換觀看紀錄或收藏;參數與資料格式見下節。 |
播放控制與即時彈幕
| type | 用途 |
|---|---|
play | 播放 |
pause | 暫停 |
stop | 停止 |
prev | 上一項 |
next | 下一項 |
repeat | 切換循環模式 |
replay | 重新播放 |
播放控制curl -G "http://127.0.0.1:9978/action" --data-urlencode "do=control" --data-urlencode "type=pause"
curl -G "http://127.0.0.1:9978/action" --data-urlencode "do=danmaku" --data-urlencode "text=範例彈幕"重新整理與推送資料
| type | 額外參數 | 用途 |
|---|---|---|
live | — | 直播 |
detail | — | 詳情 |
player | — | 播放器 |
category | — | 分類 |
subtitle | path | 字幕檔位置 |
danmaku | path | 彈幕檔位置 |
vod | json | Vod 物件的 JSON 字串 |
刷新範例curl -G "http://127.0.0.1:9978/action" --data-urlencode "do=refresh" --data-urlencode "type=category"
curl -G "http://127.0.0.1:9978/action" --data-urlencode "do=refresh" --data-urlencode "type=subtitle" --data-urlencode "path=https://example.com/subtitle.srt"
curl "http://127.0.0.1:9978/action?do=refresh&type=vod" --data-urlencode 'json={"vod_id":"demo-1","vod_name":"範例項目"}'播放、搜尋、配置與檔案
推送與設定curl -G "http://127.0.0.1:9978/action" --data-urlencode "do=push" --data-urlencode "url=https://example.com/video.m3u8"
curl -G "http://127.0.0.1:9978/action" --data-urlencode "do=search" --data-urlencode "word=範例"
curl -G "http://127.0.0.1:9978/action" --data-urlencode "do=setting" --data-urlencode "text=https://example.com/vod.json" --data-urlencode "name=示意配置"
curl -G "http://127.0.0.1:9978/action" --data-urlencode "do=file" --data-urlencode "path=/TV/subtitle.srt"do=file 依小寫副檔名分派:.apk 交給安裝流程;.srt、.ssa、.ass 交給字幕流程;其他交給設定流程。它使用裝置檔案位置,不會把電腦上的檔案上傳。
投放既有觀看紀錄
config 是 App 儲存的 Config 記錄,不是含 sites / lives 的完整配置;device 可由目標裝置的 /device 取得;history 應沿用既有 History 記錄。以下只示範表單編碼,key、設定位置與裝置位址需換成實際資料。
投放表單curl "http://127.0.0.1:9978/action?do=cast" --data-urlencode 'config={"type":0,"url":"https://example.com/vod.json","name":"示意配置"}' --data-urlencode 'device={"uuid":"demo-android-id","name":"示意電視","ip":"http://192.0.2.10:9978","type":0}' --data-urlencode 'history={"key":"demo@@@demo-1@@@7","vodName":"範例項目","vodFlag":"Demo","vodRemarks":"第 1 集","episodeUrl":"demo://episode/1","position":120000}'/action?do=sync:裝置同步
建議以表單 POST 傳送 JSON 字串。mode 的方向以「收到本次請求的 App」為準,HTTP OK 並不是配置載入或資料合併完成的確認。
| 參數 | 用途 |
|---|---|
type | history=觀看紀錄;keep=收藏。 |
mode | 0=傳送並接收(預設);1=只接收;2=只傳送。 |
device | mode 0 / 2 傳送時使用的目標 Device 物件字串;沒有 device 就不主動傳送。 |
force | 字串 true 才啟用先刪後合併;未填或其他值不先刪除。 |
config | history 使用的 Config 物件字串;接收時需要有效 url,可能先載入該配置。 |
targets | History[] 或 Keep[] 的 JSON 字串;型別依 type 決定。 |
configs | keep 使用的 Config[] 物件陣列字串,不是 URL 字串陣列;以來源 id 對應 Keep.cid。 |
收藏同步的資料關係
兩個表單欄位的解碼內容{
"configs": [
{
"id": 7,
"type": 0,
"url": "https://example.com/vod.json",
"name": "示意配置"
}
],
"targets": [
{
"key": "demo@@@demo-1@@@7",
"cid": 7,
"type": 0,
"siteName": "Demo",
"vodName": "範例項目",
"vodPic": "https://example.com/poster.jpg",
"createTime": 1788825600000
}
]
}上例不是可直接提交的 JSON body。需要將 configs 與 targets 各自序列化成表單字串;來源 Config.id 為 7,因此 Keep.cid 也為 7。App 合併時會重新對應本機配置 ID。
只接收收藏,不先刪除curl "http://127.0.0.1:9978/action?do=sync&type=keep&mode=1&force=false" --data-urlencode 'configs=[{"id":7,"type":0,"url":"https://example.com/vod.json","name":"示意配置"}]' --data-urlencode 'targets=[{"key":"demo@@@demo-1@@@7","cid":7,"type":0,"siteName":"Demo","vodName":"範例項目","vodPic":"https://example.com/poster.jpg","createTime":1788825600000}]'觀看紀錄使用 type=history、單一 config 與 History 陣列;合併會比較同名項目的 createTime,不是盲目覆寫全部紀錄。同步可能載入另一份配置,請先備份個人資料。
/media:播放狀態
查詢播放狀態curl "http://127.0.0.1:9978/media"沒有播放服務、播放器已釋放,或讀取失敗時回傳 {}。有資料時回傳以下結構;Content-Type 是 text/plain,客戶端需自行解析 JSON。
/media 回應{
"state": 3,
"speed": 1,
"duration": 7200000,
"position": 120000,
"url": "https://example.com/video.m3u8",
"title": "範例項目",
"artist": "Demo",
"artwork": "https://example.com/poster.jpg"
}| 欄位 | 類型 | 用途 | 預設 |
|---|---|---|---|
state | integer | 3=正在播放;6=緩衝中;2=就緒但未播放;其餘狀態回傳 1。 | — |
speed | number | 目前播放速率,1 表示正常速度。 | — |
duration | integer | 播放器回報的總長,單位毫秒;未知長度可能是負值,不保證為 -1。 | — |
position | integer | 目前播放位置,單位毫秒。 | — |
url | string | 目前播放 URL;沒有值時為空字串。 | — |
title | string | 媒體標題;沒有值時為空字串。 | — |
artist | string | 媒體的 artist 中繼資料;沒有值時為空字串。 | — |
artwork | string | 封面 URI;沒有值時為空字串。 | — |
/device:裝置資訊
/device 回應{
"uuid": "demo-android-id",
"name": "影視TV 示意裝置",
"ip": "http://192.0.2.10:9978",
"type": 0,
"serial": "",
"eth": "",
"wlan": "",
"time": 1788825600000
}內容為 JSON 字串,Content-Type 是 text/plain。不要把裝置識別碼或 MAC 位址填入公開範例;下方只列欄位用途。
| 欄位 | 類型 | 用途 | 預設 |
|---|---|---|---|
uuid | string | 此 App 裝置使用的 Android ID。 | — |
name | string | 裝置顯示名稱。 | — |
ip | string | 完整服務位址,包含 http://、區域網路 IP 與實際埠號。 | — |
type | integer | 0=電視版;1=手機版。Device 物件另以 2 表示 DLNA 裝置,但本機 /device 不使用此值。 | — |
serial | string | 系統可取得的裝置序號;可用性受裝置與權限限制。 | — |
eth | string | eth0 的 MAC 位址;不保證每個裝置都能取得。 | — |
wlan | string | wlan0 的 MAC 位址;不保證每個裝置都能取得。 | — |
time | integer | App 實例建立時的 Unix 時間,單位毫秒;不是這次 HTTP 回應的時間。 | — |
id | integer | 資料庫識別碼;/device 建立的是未儲存的 Device,因此通常不輸出此欄位。 | — |
檔案與目錄管理
一般相對路徑以 Android 共用外部儲存根目錄 Path.root() 為基準,不是 App 的私有 data 目錄;實際存取仍受系統儲存權限限制。
| 端點 | 使用方式 | 參數與行為 |
|---|---|---|
/file/{path} | GET | 瀏覽目錄或下載檔案;/file 為共用儲存根目錄。 |
/upload | POST multipart/form-data | path 必填且目錄須已存在;檔案使用 multipart 欄位上傳。 |
/newFolder | GET / POST | path 為既有父目錄,name 為新資料夾名稱。 |
/delFolder | GET / POST | path 必填;遞迴刪除指定項目,不可刪除儲存根目錄。 |
/delFile | GET / POST | 與 /delFolder 共用刪除邏輯,並非只允許刪除一般檔案。 |
列目錄與建立資料夾curl "http://127.0.0.1:9978/file/TV"
curl -G "http://127.0.0.1:9978/newFolder" --data-urlencode "path=TV" --data-urlencode "name=demo-empty"瀏覽 /file/TV 的示意回應{
"parent": "",
"files": [
{
"name": "demo.mp4",
"path": "/TV/demo.mp4",
"time": "2026/09/08 12:00:00",
"dir": 0
},
{
"name": "subtitles",
"path": "/TV/subtitles",
"time": "2026/09/08 12:00:00",
"dir": 1
}
]
}| 欄位 | 用途 |
|---|---|
parent | 位於根目錄時為 .;上一層是根目錄時為空字串;其他回傳上一層相對路徑。 |
files[].name | 檔案或目錄名稱。 |
files[].path | 根目錄內的路徑通常帶前導 /,例如 /TV/demo.mp4。 |
files[].time | 最後修改時間,以裝置時區格式化為 yyyy/MM/dd HH:mm:ss。 |
files[].dir | 1=目錄;0=一般檔案。 |
下載、Range 與快取
一般下載回傳 200;單一有效 Range 回傳 206,支援起迄、開放結尾及尾端位元組範圍。多段或無效範圍回傳 416;If-None-Match 命中 ETag 時回傳 304,If-Range 不符時改回完整檔案。
讀取前 1 KiBcurl "http://127.0.0.1:9978/file/TV/demo.mp4" -H "Range: bytes=0-1023" --output demo-part.bin上傳與刪除
上傳至已存在的 TV 目錄curl "http://127.0.0.1:9978/upload?path=TV" -F "file=@./subtitle.srt"multipart 欄位名稱可自訂,上例使用 file;檔名由上傳欄位提供,不能是空字串、.、.. 或包含路徑分隔符。ZIP 會解壓到指定目錄,其他檔案使用原子複製;缺少檔案、目錄不存在或操作失敗會回傳 500 與文字訊息。
刪除示意目錄curl -G "http://127.0.0.1:9978/delFolder" --data-urlencode "path=TV/demo-empty"上傳、新建與刪除都限制在共用儲存根目錄內,禁止刪除根目錄本身。/file 的區網請求也限制於此範圍;本機 loopback 請求可由 Path.local 解析其他可存取路徑。
/cache:鍵值快取
使用 GET 或表單 POST。實際儲存鍵為 "cache_" + (rule 為空 ? "" : rule + "_") + key;rule 可用來隔離不同爬蟲的名稱空間。
| do | 參數 | 回應 |
|---|---|---|
get | key、rule(選填) | 回傳儲存的字串;不存在時為空字串。 |
set | key、value、rule(選填) | 寫入字串,回傳 OK。 |
del | key、rule(選填) | 移除鍵,回傳 OK。 |
寫入、讀取與移除curl -G "http://127.0.0.1:9978/cache" --data-urlencode "do=set" --data-urlencode "rule=demo" --data-urlencode "key=greeting" --data-urlencode "value=Hello"
curl "http://127.0.0.1:9978/cache?do=get&rule=demo&key=greeting"
curl "http://127.0.0.1:9978/cache?do=del&rule=demo&key=greeting"代理與 App 內部端點
| 端點 | 參數與行為 |
|---|---|
/proxy | 把 Query / 表單參數、請求標頭、parseBody 產生的 files 依序合併後交給 BaseLoader.proxy;後加入的同名鍵會覆蓋前者。 |
/parse | jxs 為以分號分隔的解析前綴;url 為目標網址。parse.html 會以每個前綴 + url 建立 iframe,回傳 text/html。 |
/image/{key} | 讀取 ImgUtil 已快取的圖片資料,使用圖片本身的 MIME;找不到 key 時回傳 404。不是任意網址的圖片下載 API。 |
/tvbus | 回傳目前直播配置 Core 的 RESP 字串,不是頻道列表。 |
/ | 回傳 App 內建的 index.html 控制頁;其他未匹配路徑會嘗試讀取內建資源,不存在則回傳 404。 |
/proxy 的 POST body 不是一律直接攤平成參數:一般表單進入 parms,multipart 會提供暫存檔資訊,原始 body 依 NanoHTTPD 的 parseBody 結果傳遞。爬蟲回應決定狀態、Content-Type、串流與標頭;無效回應或例外會回傳 500。
解析頁範例curl -G "http://127.0.0.1:9978/parse" --data-urlencode "jxs=https://example.com/parse?url=" --data-urlencode "url=https://example.com/watch/demo-1"代理回傳格式與各語言差異請見 Spider Proxy 回傳;RESP 欄位請見 Core 配置。