Go client for the SubDL and OpenSubtitles subtitle APIs.
go get github.com/mohaanymo/subapiNo dependencies beyond the standard library.
Both sites implement the same Source interface. Find returns candidates; nothing is downloaded until you call Fetch on one, because downloads are the metered part on OpenSubtitles.
sources := []subapi.Source{
&subapi.SubDL{APIKey: subdlKey},
&subapi.OpenSubtitles{
APIKey: osKey,
Username: username,
Password: password,
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)
if err != nil {
continue
}
fmt.Println(c.Source, c.Release, len(srt))
}
}A Query takes a TMDB id, an IMDb id, or a title and year, in that order of preference. Season and Episode are 0 for a movie. An empty Lang means any language.
What Fetch returns is always one SRT file:
- SubDL serves zip archives, often a whole season even when it says otherwise. The archive is opened and the member for the requested episode is picked by its filename (
S01E02,1x02, or a bare episode number when that is unambiguous). If the episode isn't in the pack,Fetchreturns an error rather than a neighbour. - OpenSubtitles results are sorted by download count and requested as SRT. Each download costs one unit of your daily allowance (20/day free).
Pass your own *http.Client in the HTTP field to control timeouts or proxies. The default has a 60 second timeout.
SubDL Pro documents AI endpoints on its v2 API, exposed here as methods on SubDL:
sd := &subapi.SubDL{APIKey: subdlKey}
job, err := sd.Translate(ctx, nID, "FA", subapi.ToneFaithful)
job, err = sd.WaitTranslation(ctx, job.Ref(), 0)
srt, err := sd.DownloadTranslation(ctx, job)
m, err := sd.FilenameSearch(ctx, "that.movie.2021.WEBRip.mkv")
q := m.Query("en")
job, err = sd.Transcribe(ctx, "https://host/episode.mp3", "en")The nID for Translate is the ID of a SubDL candidate.
These are not live yet. Every /api/v2 path currently returns 404 while /api/v1 works with the same key. The code follows the published contract and has not been run against a live endpoint.
MIT