Playback - MiCat-S/Mi302 GitHub Wiki
This page explains what happens when a player presses play, which strm contents Mi302 understands, the playback authentication and download switches, and how to reach Mi302 from outside your network. The web admin page is in Traditional Chinese; setting names are given in English with the original label in parentheses.
- The player first calls
PlaybackInfo. Mi302 returns one media source:- For a 115 strm (with 115 signed in):
Pathis{address the player connected to}/videos/{id}/stream.{container}?Static=trueandDirectStreamUrlis/videos/{id}/stream.{container}?Static=true&MediaSourceId=…&api_key={token}. - Only direct play is offered (
SupportsTranscodingis false). Mi302 never transcodes, so the player must handle the format itself. - If media info is available it includes resolution, audio tracks and subtitle tracks. If not, and Probe when a video is opened (打開影片時自動探測) is on (the default), the item is queued for background probing, see Media Info.
- For a 115 strm (with 115 signed in):
- The player requests
/Videos/{id}/stream…. Mi302 reads the strm, applies the path rules and extracts the pickcode (the 17-character code that identifies a file on 115 Cloud (115 網盤)). It asks 115 for a download link using the player's own User-Agent and answers302 Location: <115 direct link>. - The player reads the video straight from 115. Video traffic does not pass through Mi302.
Path points back to Mi302 rather than to 115 because some players play Path directly when the source is http. Pointing it at Mi302 guarantees the request goes through Mi302 with the player's User-Agent.
A library can also hold regular video files instead of strm files. Mi302 serves those itself, with Range support (so seeking works), and that traffic does pass through Mi302.
A 115 direct link is usually tied to the User-Agent that requested it: opening it with a different UA can be refused by 115's CDN (403). 115 does not document this; it is how several 115 tools work and what users report, see the references at the end of this section. That is why Mi302 requests the link with the player's own User-Agent and redirects the player, instead of downloading on the player's behalf. If a link turns out not to be tied to the UA, playback works the same way.
- Links are cached per (pickcode, User-Agent) until 5 minutes before the expiry time in the link, or for 10 minutes if no expiry can be read.
- Concurrent requests for the same file and User-Agent share a single request to 115.
- If the 115 open platform is authorised, it is tried first and QR-code login is the fallback, see 115 Cloud Sync.
- If 115 fails: when the strm points back to Mi302 itself (same host as the address the player used, or not a URL at all), the player gets a 502 with the reason; when it points to another host, Mi302 redirects to the URL in the strm instead.
References: 115-helper (fixes Aria2's UA automatically to avoid 403), nodekit #761 (playback failed when the UA differed), OpenList's 115 driver (requests links with the client's UA). One source says the opposite: 115driver #98 reports that share links fetched with a 115 client UA are not tied to the UA.
Mi302 uses the first line of the strm that is not empty and does not start with #.
| strm content | Usually from | What Mi302 does |
|---|---|---|
http://host:8096/d/{pickcode}.mkv (optionally followed by ?/original-name) |
Mi302's own sync | Gets a 115 direct link |
…/d/{pickcode} |
Other tools, such as 115-station | Gets a 115 direct link |
…?pickcode={pickcode} or …?pick_code={pickcode}
|
P115StrmHelper and similar | Gets a 115 direct link |
115://{pickcode} |
Gets a 115 direct link | |
Any other http:// or https:// URL |
alist and similar | Redirects to that URL |
A local path, such as /mnt/media/a.mkv
|
Serves the file itself |
- When a pickcode is found and 115 is signed in, the host in the URL does not matter. strm files made by other tools work without regenerating them.
- Mi302 also answers the URLs that other tools' strm files point to:
/d/{pickcode},/p115/redirect?pickcode=…and/api/v1/plugin/p115strmhelper/redirect_url?pickcode=…. Pointing those strm files' host at Mi302 works too. These URLs do not check login. - The container comes from the URL's extension, then from a
file_name=parameter, and otherwise from Default container when the format is unknown (看不出格式時預設的影片格式, defaultmkv).
The Playback card (播放) on the Settings tab (設定) has Require login for playback URLs (播放網址要求登入, redirect.require_auth, on by default).
When it is on, /Videos/{id}/… only answers with a 302 if a valid token is sent, just like official Emby (since 4.7 Emby blocks unauthenticated stream requests on the LAN as well). The token can be sent as:
- The query parameter
api_key(alsoApiKeyorX-Emby-Token). TheDirectStreamUrlreturned byPlaybackInfoalready includes it. - The header
X-Emby-TokenorX-MediaBrowser-Token, orToken="…"insideX-Emby-Authorization.
The Emby apps and Kodi put the token in the query string; Infuse sends it in the X-Emby-Authorization header. Both work.
When it is off, anyone who knows an item id can get the 115 direct link without logging in. Only turn it off if a player cannot play because of it: first enable Verbose mode (詳細模式) on the Logs tab (日誌) and check whether /Videos/… returns 401 during playback, see Logs and FAQ.
PlaybackInfo and downloads are not affected by this switch; they always require login.
The Playback card on the Settings tab has Allow players to download videos (允許播放器下載影片, server.allow_download, on by default).
- The download URLs
/Items/{id}/Downloadand/Items/{id}/Filealways require login. Downloading a strm item is the same 302 to 115, so the player downloads straight from 115. - When the switch is off, items report
CanDownload: falseand the user policy reportsEnableContentDownloading: false, so players hide their download button. Calling a download URL directly returns 403 "下載功能已關閉" (downloads are disabled). - The switch only covers the download URLs; the playback URLs keep working.
The settings in the Other tools' strm card (其他工具產生的 strm), under Other strm (其他 strm) on the Settings tab, only matter when the strm contents were not written by Mi302 (for example alist URLs or local paths). Click Save settings (儲存設定) at the bottom of the page after changing them.
Path rules (路徑替換, redirect.path_rules): one rule per line, written as old prefix => new prefix. The strm content is rewritten before anything else happens.
- Local paths: the path prefix is compared by whole path segments, so
/mnt/115matches/mnt/115/…but not/mnt/1150. - An old prefix of
/applies to every path:/ => /mnt/nasturns/a/b.mkvinto/mnt/nas/a/b.mkv. - A rule whose old prefix is a full URL (with
http://) is compared against the whole URL, which lets you change hosts. - A rule whose old prefix is a path is also compared against the path part of a URL. On a match the whole URL becomes the new prefix plus the rest of the path (the query string is kept), so the new prefix must be a full URL in that case.
- For URLs, full-URL rules are checked before path rules; within each kind, the first matching rule from the top wins.
/mnt/115 => http://alist:5244/d/115
http://192.168.1.5:3000 => http://192.168.1.8:3000
The first rule turns /mnt/115/電影/a.mkv into http://alist:5244/d/115/電影/a.mkv, which is then used for the 302.
Resolve upstream redirects on the server (由伺服器先跟著上游的重導向走到底, redirect.resolve_redirects, off by default): Mi302 sends a HEAD request with the player's User-Agent, follows every redirect and gives the final URL to the player.
- Results are cached per (item, User-Agent) for
redirect.cache_ttlseconds (default 90); each resolution waits at mostredirect.resolve_timeoutseconds (default 10). Both can only be set in the config file, andresolve_timeoutneeds a restart. - On failure the original URL is used.
- strm files with a pickcode get their 115 direct link directly and skip this step.
Default container when the format is unknown (redirect.default_container, default mkv) tells the player which format to expect when the strm URL has no extension.
Players report progress through /Sessions/Playing, /Sessions/Playing/Progress and /Sessions/Playing/Stopped (and the older /Users/{id}/PlayingItems/{id}).
- The resume position is stored per user.
- Stopping at 90% of the runtime or later marks the item watched, adds one to the play count and clears the resume position. The runtime comes from the nfo, the media info, or the runtime the player reports.
- A report without a position only updates the last-played time and leaves the resume position alone.
- The same reports are used to learn intros and credits, see Intro and Credits.
Video goes straight from 115 to the player. Mi302 and the reverse proxy only handle API requests and small 302 responses, so your home upload bandwidth barely matters. The exceptions are regular video files in a library and strm files that contain local paths; those pass through Mi302.
Mi302 itself only speaks HTTP. For HTTPS from outside, put a reverse proxy such as Caddy or Nginx in front of it:
- Use a dedicated domain or subdomain and forward the whole site to Mi302. Under a sub-path (for example
/mi302/), the playback URLs Mi302 returns will not contain that sub-path. - Pass the original
Hostheader andX-Forwarded-Proto. Mi302 honoursX-Forwarded-ProtoandX-Forwarded-Forand builds the playback URL inPlaybackInfofrom the address the player connected to; with a wrongHost, players get a wrong address. - The WebSocket at
/embywebsocketonly answers KeepAlive messages. Forwarding it is optional; the example below does. - If MoviePilot's cover plugin uploads through the proxy, allow request bodies of 30 MB.
Caddy (passes Host and X-Forwarded-Proto by default and obtains certificates automatically):
emby.example.com {
reverse_proxy 127.0.0.1:8096
}
Nginx:
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 443 ssl;
server_name emby.example.com;
ssl_certificate /etc/ssl/emby.example.com.crt;
ssl_certificate_key /etc/ssl/emby.example.com.key;
client_max_body_size 30m;
location / {
proxy_pass http://127.0.0.1:8096;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
}In the player, use https://emby.example.com as the server address.
The Sync options card (同步選項) on the 115 Cloud tab (115 網盤) has Server URL in strm files (strm 裡的伺服器網址, p115.strm.base_url). Left empty, Mi302 uses the address the admin most recently used to open the web admin page.
When Mi302 plays a strm itself, it only extracts the pickcode and ignores the host, so remote playback works without changing this setting. You only need to set your public address when other programs read these strm files directly (for example another Emby server, or a player that opens the strm files over SMB) and must reach Mi302 from outside.
Set it to the reverse proxy's public address (a sub-path works, for example https://example.com/mi302) and save; the existing strm files are then rewritten in the background. That only touches local files, makes no requests to 115 and needs no sync; see 115 Cloud Sync. The reverse proxy must pass requests starting with /d/ to Mi302 unchanged and keep the player's User-Agent (115 direct links are usually tied to it, see above; Nginx and Caddy keep it by default). During playback Mi302 still fetches a 115 direct link and redirects the player to it, so the video does not go through the proxy.
- Keep Require login for playback URLs on and use strong passwords.
- Password guessing is limited: after 5 wrong passwords in a row for one account from one source, the next attempt has to wait (30 seconds at first, doubling with each further mistake, up to 15 minutes), even with the right password. This applies to player logins and WebDAV alike, and resets after a successful login or 15 minutes without a mistake.
- Consider turning off List user names on the player login screen (播放器登入畫面列出使用者名稱,
server.public_users) in the Server card, so the login screen does not list accounts. - The web admin page
/webis only available to admin accounts, and API keys cannot call its API. - The strm short links
/d/{pickcode}do not check login, but they require knowing the 17-character pickcode. When too many requests fail to get a link (10 a minute from one source, or 60 a minute overall), Mi302 answers 429 and stops asking 115 for them; links fetched a moment ago are still served. - WebDAV requires a user name and password; turn on Administrators only when exposing the whole of 115.
If you would rather not create strm files, or a player does not support Emby, it can browse 115 directly over WebDAV. Turn it on under WebDAV on the Settings tab (設定); it takes effect as soon as you save.
- Read only: browsing and playing. Deleting, renaming, uploading and creating folders are refused.
- Playback works like strm: Mi302 fetches the 115 direct link with the player's own User-Agent and redirects with a 302. Video never passes through Mi302.
- Sign-in: your Mi302 user name and password (HTTP Basic). Changing the password or deleting the user locks them out immediately. It can be limited to administrators.
-
What is exposed: by default only the 115 folders of the sync tasks (their parent folders show just the way down to them). You can instead enter a 115 folder such as
/Videos, or/for the whole of 115 (turn on Administrators only as well). Paths outside that, including ones climbing out with.., return "not found". -
Paths are the 115 paths:
/dav/Videos/Movies/x.mkvis/Videos/Movies/x.mkvon 115, and case matters.
In the player, add a WebDAV source with the server http://<host>:8096/dav/ (or host and port separately with the path /dav/) and your Mi302 user name and password:
- Infuse: add a file source (share) → WebDAV.
- VidHub: add a cloud drive → WebDAV.
- Kodi: add video source → Browse → Add network location → protocol WebDAV server (HTTP).
Folder listings come from 115 live; the same folder is not asked again within 2 minutes. A player indexing a whole folder for the first time (Infuse's library, for example) asks many times, so the smaller the exposed folder, the less likely 115 rate-limits you. If it does, Mi302's circuit breaker trips and listings fail for a while; playback keeps working. WebDAV has none of Mi302's watch history, intro skipping or media info; those need the Emby sign-in. After a folder is moved out of the exposed scope on 115, its old path (and the files under it) stops working within 2 minutes.
From outside your network, go through an HTTPS reverse proxy: HTTP Basic only encodes the password, it does not encrypt it.
Testing: at the bottom of the WebDAV tab, enter a Mi302 user name and password and click Test WebDAV (測試 WebDAV). It connects to /dav/ from the address you opened the admin page with (so a reverse proxy is tested too), then checks that each exposed 115 folder can be read, and tells apart: not turned on, wrong user name or password, not an administrator while Administrators only is on, a response that did not come from Mi302 (the reverse proxy does not forward /dav/ or blocks PROPFIND), and a folder missing on 115. It tests the saved settings.
Setting the exposed folder to / (the whole of 115) without Administrators only asks for confirmation when you click Save settings (儲存設定): every Mi302 user will be able to see and play every file on the drive.
Infuse, VidHub, SenPlayer, the official Emby apps and other players that support Emby can log in and play directly. Add an Emby server in the player with the address http://<host>:8096 (or your reverse proxy's HTTPS address) and log in with a Mi302 account.
If a player cannot connect or play, see Logs and FAQ.