本地 HTTP API

透過 App 內建的 HTTP 服務,查詢播放狀態、推送內容、管理檔案與交換裝置資料。以下按目前程式碼核對,不是 GitHub Pages 網站提供的 API。

先確認連線位址

服務從埠號 9978 依序嘗試到 9998,使用第一個成功啟動的埠。請先啟動 App,依 App 顯示的實際位址連線。

127.0.0.1 指的是發出請求的裝置下方範例以 App 裝置本機為例。若從電腦或另一台手機操作,請把 127.0.0.1:9978 換成 App 的區域網路 IP 與埠號。範例中的 example.com 與 192.0.2.10 僅作結構示意。
HTTP連線測試
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。

OK 不等於動作已完成/action 通常先派送事件或排入主執行緒再回傳 OK;未知指令、缺少必要內容或沒有播放服務,也可能回傳 OK 而未執行。這些端點沒有通用 token 驗證,請只在可信任的區域網路使用,不要直接開放到公網。

/action:動作指令

使用 GET 或表單 POST,透過 do 選擇操作。下列參數都屬於同一次請求。

do參數用途
controltype控制目前播放器;可用指令見下表。
danmakutext送出一條即時彈幕;需要有效的播放服務與非空文字。
refreshtype;依類型加 path 或 json重新整理頁面,或推送字幕、彈幕及 Vod 更新。
pushurl把非空 URL 交給 App 推送播放流程。
filepath開啟裝置上的檔案;不是上傳檔案。
searchword把非空關鍵字交給 App 搜尋介面。
settingtext、name(選填)把配置位置或設定文字交給設定流程;text 不可為空。
castconfig、device、history三者均為 JSON 物件字串,交給 App 投放事件處理。
synctype、mode、force 等交換觀看紀錄或收藏;參數與資料格式見下節。

播放控制與即時彈幕

type用途
play播放
pause暫停
stop停止
prev上一項
next下一項
repeat切換循環模式
replay重新播放
HTTP播放控制
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分類
subtitlepath字幕檔位置
danmakupath彈幕檔位置
vodjsonVod 物件的 JSON 字串
HTTP刷新範例
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":"範例項目"}'

播放、搜尋、配置與檔案

HTTP推送與設定
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、設定位置與裝置位址需換成實際資料。

HTTP投放表單
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 並不是配置載入或資料合併完成的確認。

參數用途
typehistory=觀看紀錄;keep=收藏。
mode0=傳送並接收(預設);1=只接收;2=只傳送。
devicemode 0 / 2 傳送時使用的目標 Device 物件字串;沒有 device 就不主動傳送。
force字串 true 才啟用先刪後合併;未填或其他值不先刪除。
confighistory 使用的 Config 物件字串;接收時需要有效 url,可能先載入該配置。
targetsHistory[] 或 Keep[] 的 JSON 字串;型別依 type 決定。
configskeep 使用的 Config[] 物件陣列字串,不是 URL 字串陣列;以來源 id 對應 Keep.cid。
force=true 會刪除既有資料history 先刪除對應配置的觀看紀錄;keep 呼叫 Keep.deleteAll()。一般同步請省略 force 或傳 false,不要使用空 targets 測試清除流程。

收藏同步的資料關係

JSON / Sync兩個表單欄位的解碼內容
{
  "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。

HTTP只接收收藏,不先刪除
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:播放狀態

HTTP查詢播放狀態
curl "http://127.0.0.1:9978/media"

沒有播放服務、播放器已釋放,或讀取失敗時回傳 {}。有資料時回傳以下結構;Content-Type 是 text/plain,客戶端需自行解析 JSON。

JSON / Media/media 回應
{
  "state": 3,
  "speed": 1,
  "duration": 7200000,
  "position": 120000,
  "url": "https://example.com/video.m3u8",
  "title": "範例項目",
  "artist": "Demo",
  "artwork": "https://example.com/poster.jpg"
}
欄位類型用途預設
stateinteger3=正在播放;6=緩衝中;2=就緒但未播放;其餘狀態回傳 1。
speednumber目前播放速率,1 表示正常速度。
durationinteger播放器回報的總長,單位毫秒;未知長度可能是負值,不保證為 -1。
positioninteger目前播放位置,單位毫秒。
urlstring目前播放 URL;沒有值時為空字串。
titlestring媒體標題;沒有值時為空字串。
artiststring媒體的 artist 中繼資料;沒有值時為空字串。
artworkstring封面 URI;沒有值時為空字串。

/device:裝置資訊

JSON / 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 位址填入公開範例;下方只列欄位用途。

欄位類型用途預設
uuidstring此 App 裝置使用的 Android ID。
namestring裝置顯示名稱。
ipstring完整服務位址,包含 http://、區域網路 IP 與實際埠號。
typeinteger0=電視版;1=手機版。Device 物件另以 2 表示 DLNA 裝置,但本機 /device 不使用此值。
serialstring系統可取得的裝置序號;可用性受裝置與權限限制。
ethstringeth0 的 MAC 位址;不保證每個裝置都能取得。
wlanstringwlan0 的 MAC 位址;不保證每個裝置都能取得。
timeintegerApp 實例建立時的 Unix 時間,單位毫秒;不是這次 HTTP 回應的時間。
idinteger資料庫識別碼;/device 建立的是未儲存的 Device,因此通常不輸出此欄位。

檔案與目錄管理

一般相對路徑以 Android 共用外部儲存根目錄 Path.root() 為基準,不是 App 的私有 data 目錄;實際存取仍受系統儲存權限限制。

端點使用方式參數與行為
/file/{path}GET瀏覽目錄或下載檔案;/file 為共用儲存根目錄。
/uploadPOST multipart/form-datapath 必填且目錄須已存在;檔案使用 multipart 欄位上傳。
/newFolderGET / POSTpath 為既有父目錄,name 為新資料夾名稱。
/delFolderGET / POSTpath 必填;遞迴刪除指定項目,不可刪除儲存根目錄。
/delFileGET / POST與 /delFolder 共用刪除邏輯,並非只允許刪除一般檔案。
HTTP列目錄與建立資料夾
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"
JSON / Folder瀏覽 /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[].dir1=目錄;0=一般檔案。

下載、Range 與快取

一般下載回傳 200;單一有效 Range 回傳 206,支援起迄、開放結尾及尾端位元組範圍。多段或無效範圍回傳 416;If-None-Match 命中 ETag 時回傳 304,If-Range 不符時改回完整檔案。

HTTP讀取前 1 KiB
curl "http://127.0.0.1:9978/file/TV/demo.mp4" -H "Range: bytes=0-1023" --output demo-part.bin

上傳與刪除

HTTP上傳至已存在的 TV 目錄
curl "http://127.0.0.1:9978/upload?path=TV" -F "file=@./subtitle.srt"

multipart 欄位名稱可自訂,上例使用 file;檔名由上傳欄位提供,不能是空字串、.、.. 或包含路徑分隔符。ZIP 會解壓到指定目錄,其他檔案使用原子複製;缺少檔案、目錄不存在或操作失敗會回傳 500 與文字訊息。

刪除端點會直接刪除資料/delFile 與 /delFolder 目前使用同一段遞迴刪除程式;不要依端點名稱假設目錄不會被刪除。下例只針對先前建立的示意目錄,執行前務必確認內容。
HTTP刪除示意目錄
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參數回應
getkey、rule(選填)回傳儲存的字串;不存在時為空字串。
setkey、value、rule(選填)寫入字串,回傳 OK。
delkey、rule(選填)移除鍵,回傳 OK。
HTTP寫入、讀取與移除
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;後加入的同名鍵會覆蓋前者。
/parsejxs 為以分號分隔的解析前綴;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。

HTTP解析頁範例
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 配置