Skip to content

Commit

Permalink
update opensubtitles api
Browse files Browse the repository at this point in the history
  • Loading branch information
howardchung committed Jan 21, 2025
1 parent 27d2b21 commit 7a519b3
Show file tree
Hide file tree
Showing 3 changed files with 124 additions and 122 deletions.
1 change: 1 addition & 0 deletions server/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ const defaults = {
MEDIASOUP_SERVER: '', // Optional, URL of the MediaSoup server to broadcast to for larger screen/file shares
TWITCH_PROXY_PATH: '', // Optional, URL of the server that can proxy twitch HLS stream playlists and segments
VBROWSER_ADMIN_KEY: '', // Optional, the key to hit admin endpoints on the vbrowser
OPENSUBTITLES_KEY: '', // Optional, key to OpenSubtitles API
};

export default {
Expand Down
61 changes: 45 additions & 16 deletions server/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import path from 'path';
import { getStartOfDay } from './utils/time';
import { getBgVMManagers, getSessionLimitSeconds } from './vm/utils';
import { postgres, insertObject, upsertObject } from './utils/postgres';
import axios from 'axios';
import axios, { isAxiosError } from 'axios';
import crypto from 'crypto';
import zlib from 'zlib';
import util from 'util';
Expand Down Expand Up @@ -140,13 +140,39 @@ app.post('/subtitle', async (req, res) => {
});

app.get('/downloadSubtitles', async (req, res) => {
const response = await axios.get(req.query.url as string, {
responseType: 'arraybuffer',
});
res.append('Content-Encoding', 'gzip');
res.append('Content-Type', 'text/plain');
redisCount('subDownloadsOS');
res.end(response.data);
// Request the URL from OS
try {
const urlResp = await axios({
url: 'https://api.opensubtitles.com/api/v1/download',
method: 'POST',
headers: {
'User-Agent': 'watchparty v1',
'Api-Key': config.OPENSUBTITLES_KEY,
Accept: 'application/json',
'Content-Type': 'application/json',
// 'Authorization': 'Bearer ' + config.OPENSUBTITLES_KEY,
},
data: {
file_id: req.query.file_id,
// sub_format: 'srt',
},
});
// console.log(urlResp.data);
const url = urlResp.data.link;
const response = await axios.get(url, {
responseType: 'arraybuffer',
});
// res.append('Content-Encoding', 'gzip');
res.append('Content-Type', 'text/plain');
redisCount('subDownloadsOS');
// console.log(response.data);
res.end(response.data);
} catch (e) {
if (isAxiosError(e)) {
console.log(e.response);
}
throw e;
}
});

app.get('/searchSubtitles', async (req, res) => {
Expand Down Expand Up @@ -178,19 +204,22 @@ app.get('/searchSubtitles', async (req, res) => {
let hash = computeOpenSubtitlesHash(start, end, size);
// hash = 'f65334e75574f00f';
// Search API for subtitles by hash
subUrl = `https://rest.opensubtitles.org/search/moviebytesize-${size}/moviehash-${hash}/sublanguageid-eng`;
subUrl = `https://api.opensubtitles.com/api/v1/subtitles?moviehash=${hash}&languages=en`;
} else if (title) {
subUrl = `https://rest.opensubtitles.org/search/query-${encodeURIComponent(
title,
)}/sublanguageid-eng`;
subUrl = `https://api.opensubtitles.com/api/v1/subtitles?query=${title}&languages=en`;
}
console.log(subUrl);
// Alternative, web client calls this to get back some JS with the download URL embedded
// https://www.opensubtitles.com/nocache/download/7585196/subreq.js?file_name=Borgen.S04E01.en&locale=en&np=true&sub_frmt=srt&subtitle_id=6615808&ext_installed=false
// Up to 10 downloads per IP per day, but proxyable and doesn't require key
const response = await axios.get(subUrl, {
headers: { 'User-Agent': 'VLSub 0.10.2' },
headers: {
'User-Agent': 'watchparty v1',
'Api-Key': config.OPENSUBTITLES_KEY,
},
});
// console.log(response);
// console.log(subUrl, response.data);
const subtitles = response.data;
res.json(subtitles);
res.json(subtitles.data);
} catch (e: any) {
console.error(e.message);
res.json([]);
Expand Down
184 changes: 78 additions & 106 deletions src/components/Modal/SubtitleModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,60 @@ export class SubtitleModal extends React.Component<{
{config.NODE_ENV === 'development' && (
<Input value={this.props.roomSubtitle} />
)}
{
<Input
value={this.state.titleQuery}
onChange={(e, { value }) =>
this.setState({ titleQuery: value })
}
/>
}
<div>
<Button
loading={this.state.loading}
color="green"
disabled={!this.props.haveLock()}
icon
labelPosition="left"
size="mini"
onClick={async () => {
this.setState({ loading: true });
const resp = await window.fetch(
serverPath +
'/searchSubtitles?title=' +
this.state.titleQuery,
);
const json = await resp.json();
this.setState({ searchResults: json });
this.setState({ loading: false });
}}
>
<Icon name="search" />
OpenSubtitles by Title
</Button>
<Button
loading={this.state.loading}
color="blue"
disabled={!this.props.haveLock()}
icon
labelPosition="left"
size="mini"
onClick={async () => {
this.setState({ loading: true });
const resp = await window.fetch(
serverPath +
'/searchSubtitles?url=' +
this.props.roomMedia,
);
const json = await resp.json();
this.setState({ searchResults: json });
this.setState({ loading: false });
}}
>
<Icon name="search" />
OpenSubtitles by Hash
</Button>
</div>
<div>
<Radio
disabled={!this.props.haveLock()}
Expand All @@ -111,26 +165,6 @@ export class SubtitleModal extends React.Component<{
}}
/>
</div>
{this.context.beta && (
<div>
<Radio
disabled={!this.props.haveLock()}
name="radioGroup"
label=".srt extension appended to current video URL"
value=""
checked={Boolean(
this.props.roomSubtitle &&
this.props.roomSubtitle?.startsWith(
this.props.roomMedia,
),
)}
onClick={(e, data) => {
const subValue = this.props.roomMedia + '.srt';
this.props.socket.emit('CMD:subtitle', subValue);
}}
/>
</div>
)}
<div>
<Radio
disabled={!this.props.haveLock()}
Expand All @@ -156,96 +190,34 @@ export class SubtitleModal extends React.Component<{
Upload (.srt)
</Button>
</div>
{!this.state.searchResults.length && (
<div>
<Radio
disabled={!this.props.haveLock()}
name="radioGroup"
value=""
checked={
Boolean(this.props.roomSubtitle) &&
this.props.roomSubtitle?.startsWith(
serverPath + '/downloadSubtitle',
)
}
/>
{this.context.beta && (
<Input
value={this.state.titleQuery}
onChange={(e, { value }) =>
this.setState({ titleQuery: value })
}
/>
)}
<Button
style={{ marginLeft: '8px' }}
loading={this.state.loading}
color="green"
disabled={!this.props.haveLock()}
icon
labelPosition="left"
size="mini"
onClick={async () => {
this.setState({ loading: true });
const resp = await window.fetch(
serverPath +
'/searchSubtitles?title=' +
this.state.titleQuery,
);
const json = await resp.json();
this.setState({ searchResults: json });
this.setState({ loading: false });
}}
>
<Icon name="search" />
Search by Title
</Button>
{this.context.beta && (
<Button
style={{ marginLeft: '8px' }}
loading={this.state.loading}
color="green"
{this.state.searchResults.map(
(result: {
id: string;
type: string;
attributes: Record<string, any>;
}) => (
<div>
<Radio
disabled={!this.props.haveLock()}
icon
labelPosition="left"
size="mini"
onClick={async () => {
this.setState({ loading: true });
const resp = await window.fetch(
serverPath +
'/searchSubtitles?url=' +
this.props.roomMedia,
label={result.attributes.release}
name="radioGroup"
value={result.attributes.files[0]?.file_id}
checked={
this.props.roomSubtitle ===
serverPath +
'/downloadSubtitles?file_id=' +
result.attributes.files[0]?.file_id
}
onChange={(e, { value }) => {
this.props.socket.emit(
'CMD:subtitle',
serverPath + '/downloadSubtitles?file_id=' + value,
);
const json = await resp.json();
this.setState({ searchResults: json });
this.setState({ loading: false });
}}
>
<Icon name="search" />
Search by Hash
</Button>
)}
</div>
/>
</div>
),
)}
{this.state.searchResults.map((result: any) => (
<div>
<Radio
disabled={!this.props.haveLock()}
label={result.SubFileName}
name="radioGroup"
value={result.SubDownloadLink}
checked={this.props.roomSubtitle?.includes(
result.SubDownloadLink,
)}
onChange={(e, { value }) => {
this.props.socket.emit(
'CMD:subtitle',
serverPath + '/downloadSubtitles?url=' + value,
);
}}
/>
</div>
))}
</div>
</Modal.Description>
</Modal.Content>
Expand Down

0 comments on commit 7a519b3

Please sign in to comment.