m314

Open-sourcevideo tools

For streaming video, decryption and subtitle timing. Each one is documented, MIT licensed and tested on real streams.

Get m314dlSee all three tools

Pick a tool

Download a stream, check its subtitles, fetch more. Three tools, all open source.

m314dl

★ 32CLIv0.3.6

MIT · Linux, macOS, Windows

Downloads HLS and DASH and decrypts CENC and cbcs with the keys you supply, in the same pass. There is no mp4decrypt step.

Homebrew

brew install m314dev/tap/m314dl

Scoop

scoop bucket add m314dev https://github.com/m314dev/scoop-bucket
scoop install m314dl

Go

go install github.com/m314dev/m314dl@latest

Docker

docker run --rm -v "$PWD:/data" ghcr.io/m314dev/m314dl -o out.mp4 <url>
  • cenc, cbcs, cens and cbc1 decrypted in memory, one fragment at a time
  • HLS, DASH, Smooth Streaming, plain files and M3U playlists
  • Records live streams and serves them again as HLS, MPEG-TS or DASH
  • Resumes byte for byte after a hard kill

Read the docsSource on GitHub

$ m314dl -sv 'res=1680:for=best' -sa best -o tos.mp4 https://demo.unified-streaming.com/k8s/features/stable/video/tears-of-steel/tears-of-steel.ism/.mpd
selected: video_eng=2200000.1.4 video 1680x750 2200kbps avc1.640028 [en] (video_eng=2200000)
selected: audio_eng=128002.0.1 audio 128kbps mp4a.40.2 [en] (audio_eng=128002)
100.0% | 370/370 segs | 194.6MiB | 2.3MiB/s
done: tos.mp4

Every number on this page comes from a real run: the seconds below, the film, and the two subtitle files.

Tears of Steel, as m314dl saved it: Thom and Celia argue on a bridge over a canalTears of Steel: a man with a glowing eye implant beside a woman holding a camera rigTears of Steel: Thom on a canal bridge beside a giant robot

Faster in every case

Seconds for each tool to download, decrypt and mux the same 5-minute 1080p stream, best of three. Shorter is better. The harness is in bench/, so you can run it on your own machine.

m314dl vsd 0.5.0 N_m3u8DL-RE 0.6.0

m314ss

★ 8CLI · library

MIT · needs FFmpeg

Listens to a video’s audio to decide whether a subtitle belongs to it. If it does, it fixes the timing. If not, it writes nothing.

Command line

go install github.com/m314dev/m314ss/cmd/m314ss@latest

Library

go get github.com/m314dev/m314ss
  • Lines up cue starts with speech found in the audio, never with filenames
  • Rejects a subtitle unless sigma and lift both clear 5
  • Fixes offsets up to ±120 s and 23.976, 24 and 25 fps drift
  • Finds candidates on SubDL and OpenSubtitles through subapi

Read the docsSource on GitHub

A frame from Tears of Steel with the line “The world’s changed, Celia...” after m314ss moved the subtitle 0.35 seconds
$ m314ss -srt tos_en.srt -video tos.mp4 -o tos_en.synced.srt
tos_en.synced.srt  (sigma 5.1, +0.35s)
$ m314ss -srt sintel_en.srt -video tos.mp4 -o /dev/null
subtitle does not fit this video (sigma 4.5, need 5.0)

How m314ss decides

tos_en.srt · 76 cues

1
00:00:23,000 --> 00:00:24,500
You're a jerk, Thom.

2
00:00:25,000 --> 00:00:27,000
Look Celia, we have to follow
our passions;

From Wikimedia Commons. Nobody has checked it against this cut of the film.

First the subtitle arrives, timing unchecked.

tos.mp4 · 12:14 of audio

Celia in close-up, one of the film's speaking scenes

speech starts cue starts

157

places where someone starts talking, found in the audio. The subtitle has 76 cue starts to line up against them.

Then it finds where speech starts.

offset search · −120 s to +120 s

Best: +0.35 s, one sharp spike. The dashed line is chance, 14.7%.

Best: −79.00 s, one of several bumps. The dashed line is chance, 16.2%.

Then it tries every offset.

verdict · its own subtitle

Match

  • sigma 5.12 (needs 5)
  • lift 23.4 points (needs 5)
  • shift +0.35s
The cue “I'm freaked out! I have nightmares that I'm being chased...” on screen after the shift

verdict · Sintel's subtitle

No match

  • sigma 4.47 (needs 5)
  • lift 33.8 points (needs 5)

Lift alone would have let this one through. The spread of the whole search is what rejects it, and nothing gets written.

Last, one offset stands out, or none does.

subapi

★ 1Go library

MIT · standard library only

One Source interface for SubDL and OpenSubtitles. Find returns candidates, and nothing downloads until you call Fetch.

Go

go get github.com/m314dev/subapi
  • Search by TMDB id, IMDb id, or title and year
  • Season packs opened to the episode you asked for, never a neighbour
  • OpenSubtitles results sorted by download count
  • Your own *http.Client for timeouts and proxies

Read the docsSource on GitHub

// one query, two sites; nothing downloads until Fetch
sources := []subapi.Source{
    &subapi.SubDL{APIKey: subdlKey},
    &subapi.OpenSubtitles{APIKey: osKey, UserAgent: "myapp v1.0"},
}
q := subapi.Query{TMDBID: 1396, Season: 1, Episode: 1, Lang: "ar"}

for _, src := range sources {
    cands, err := src.Find(ctx, q)
    if err != nil { continue }
    for _, c := range cands {
        srt, err := c.Fetch(ctx) // one SRT, even from a season pack
        if err == nil { fmt.Println(c.Source, c.Release, len(srt)) }
    }
}

Open source, all of it

Every tool here is MIT licensed, with its tests and its benchmark harness in the repo. Use it, fork it, send a fix.

Star a repo

New releases land on GitHub first. Star a tool to hear about them, or open an issue when a stream or a subtitle trips it up.

m314 on GitHub

Let’s talk

Hiring for video, or running m314dl or m314ss in production and need a hand? I answer every email.

About me