-
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #36 from hockyy/feature/34
[#34] Add support to watch youtube video in Miteiru
- Loading branch information
Showing
11 changed files
with
641 additions
and
114 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
const fs = require('fs-extra'); | ||
const path = require('path'); | ||
|
||
const sourceDir = path.join(__dirname, 'renderer', 'public'); | ||
const destDir = path.join(__dirname, 'app'); | ||
|
||
fs.copy(sourceDir, destDir) | ||
.then(() => console.log('Files copied successfully!')) | ||
.catch(err => console.error(err)); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
/* @flow */ | ||
|
||
import axios from 'axios'; | ||
import {find} from 'lodash'; | ||
import {decode} from 'html-entities'; | ||
|
||
function stripTags(input, allowedTags = [], replacement = '') { | ||
// Create a string of allowed tags, joined by '|' | ||
let tags = allowedTags.join('|'); | ||
|
||
// Create a new RegExp object | ||
let regex = new RegExp(`<(?!\/?(${tags})[^>]*)\/?.*?>`, 'g'); | ||
|
||
// Replace disallowed tags with replacement string | ||
return input.replace(regex, replacement); | ||
} | ||
|
||
export async function getSubtitles({videoID, lang = 'ja'}) { | ||
const {data} = await axios.get( | ||
`https://youtube.com/watch?v=${videoID}` | ||
); | ||
|
||
// * ensure we have access to captions data | ||
if (!data.includes('captionTracks')) | ||
throw new Error(`Could not find captions for video: ${videoID}`); | ||
|
||
const regex = /({"captionTracks":.*isTranslatable":(true|false)}])/; | ||
const [match] = regex.exec(data); | ||
const {captionTracks} = JSON.parse(`${match}}`); | ||
|
||
const subtitle = | ||
find(captionTracks, { | ||
vssId: `.${lang}`, | ||
}) || | ||
find(captionTracks, { | ||
vssId: `a.${lang}`, | ||
}) || | ||
find(captionTracks, ({vssId}) => vssId && vssId.match(`.${lang}`)); | ||
|
||
// * ensure we have found the correct subtitle lang | ||
if (!subtitle || (subtitle && !subtitle.baseUrl)) | ||
throw new Error(`Could not find ${lang} captions for ${videoID}`); | ||
|
||
const {data: transcript} = await axios.get(subtitle.baseUrl); | ||
return transcript | ||
.replace('<?xml version="1.0" encoding="utf-8" ?><transcript>', '') | ||
.replace('</transcript>', '') | ||
.split('</text>') | ||
.filter(line => line && line.trim()) | ||
.map(line => { | ||
const startRegex = /start="([\d.]+)"/; | ||
const durRegex = /dur="([\d.]+)"/; | ||
|
||
const [, start] = startRegex.exec(line); | ||
const [, dur] = durRegex.exec(line); | ||
|
||
const htmlText = line | ||
.replace(/<text.+>/, '') | ||
.replace(/&/gi, '&') | ||
.replace(/<\/?[^>]+(>|$)/g, ''); | ||
const decodedText = decode(htmlText); | ||
const text = stripTags(decodedText); | ||
|
||
return { | ||
start, | ||
dur, | ||
text, | ||
}; | ||
}); | ||
} |
Oops, something went wrong.