[wip] Can now extract subtitles from local video and torrents into streaming feature

This commit is contained in:
Kylart 2018-03-21 06:01:59 +01:00
parent 0e7ebc11ce
commit daeebed9e4
8 changed files with 103 additions and 51 deletions

View File

@ -18,7 +18,7 @@ export default {
},
methods: {
close () {
if (document.fullscreenElement == null) {
if (document.fullscreenElement === null) {
this.$store.commit('videoPlayer/close')
}
}

View File

@ -129,19 +129,25 @@
console.log(`[${(new Date()).toLocaleTimeString()}]: Requested to play ${item.name} - ${item.ep}. Sending...`)
// No need to get through store.
this.$axios.get(`openThis`, {
params: {
type: 'video',
path: item.path,
dir: this.$store.state.localFiles.dir
}
}).then((res) => {
if (res.status !== 200) { console.log('An error occurred: request to open file ended with a status ' + res.status + '.') }
// this.$axios.get(`openThis`, {
// params: {
// type: 'video',
// path: item.path,
// dir: this.$store.state.localFiles.dir
// }
// }).then((res) => {
// if (res.status !== 200) { console.log('An error occurred: request to open file ended with a status ' + res.status + '.') }
this.$store.dispatch('history/append', {
type: 'Play',
text: `${item.name} - ${item.ep}`
}).catch(err => { void (err) })
// this.$store.dispatch('history/append', {
// type: 'Play',
// text: `${item.name} - ${item.ep}`
// }).catch(err => { void (err) })
// })
this.$store.commit('videoPlayer/play', {
show: true,
link: {
link: item.path
}
})
},
delThis (item) {

View File

@ -190,7 +190,6 @@
: ''
},
watch (item) {
console.log(item)
this.$store.commit('videoPlayer/play', {
show: true,
link: {

View File

@ -20,7 +20,7 @@ const setup = (app) => {
nyaa: require('./nyaa'),
openExternal: require('./openExternal'),
seasons: require('./seasons'),
torrent: require('./torrent'),
video: require('./video'),
search: require('./search'),
wl: require('./watchList')
}

View File

@ -37,7 +37,7 @@ const getUniques = (files) => {
return result
}
const sendFiles = (json, files, res) => {
const sendFiles = (json, dir, files, res) => {
const result = []
logger.info('Sending files.')
@ -47,7 +47,7 @@ const sendFiles = (json, files, res) => {
if (name) {
const tmp = JSON.parse(JSON.stringify(json[minifyName(name)]))
tmp.ep = getEp(file)
tmp.path = file
tmp.path = join(dir, file)
result.push(tmp)
}
})
@ -67,7 +67,7 @@ const searchLocalFiles = ({query}, res) => {
let counter = 0
if (!files.length) {
sendFiles(json, [], res)
sendFiles(json, DIR, [], res)
} else {
uniqueNames.forEach((elem) => {
// Search MAL for each name if not in json
@ -96,7 +96,7 @@ const searchLocalFiles = ({query}, res) => {
logger.info('Successfully saved data.')
sendFiles(json, files, res)
sendFiles(json, DIR, files, res)
}
}).catch(/* istanbul ignore next */(err) => {
logger.error('An error occurred.', err)
@ -105,7 +105,7 @@ const searchLocalFiles = ({query}, res) => {
} else {
++counter
/* istanbul ignore next */
if (counter === uniqueNames.length) sendFiles(json, files, res)
if (counter === uniqueNames.length) sendFiles(json, DIR, files, res)
}
})
}

View File

@ -1,4 +1,4 @@
const {stream, tracks} = require('./torrent.js')
const {stream, tracks} = require('./streaming.js')
const sseExpress = require('sse-express')
const routes = [

25
server/video/local.js Normal file
View File

@ -0,0 +1,25 @@
const fs = require('fs')
const MatroskaSubtitles = require('matroska-subtitles')
const { Logger } = require('../utils')
const logger = new Logger('Local')
const getSubtitles = (req, res) => {
const { query: { path } } = req
logger.info('Extracting subtitles from file:', path)
const parser = new MatroskaSubtitles()
parser.once('tracks', tracks => res.sse('tracks', tracks))
parser.on('subtitle', (subtitle, trackNumber) => res.sse('subtitle', {
subtitle,
trackNumber
}))
fs.createReadStream(path).pipe(parser)
}
module.exports = {
getSubtitles
}

View File

@ -1,3 +1,4 @@
const fs = require('fs')
const WebTorrent = require('webtorrent')
const parseRange = require('range-parser')
const mime = require('mime')
@ -6,9 +7,10 @@ const logger = new Logger('Torrent Streamer')
const decode = require('urldecode')
const MatroskaSubtitles = require('matroska-subtitles')
const client = new WebTorrent()
const client = process.torrentClient = new WebTorrent()
const stream = (req, res) => {
// Getting magnet hash
const magnet = decode(req.url.slice('/stream/'.length))
logger.info(`Streaming magnet: ${magnet}`)
@ -21,19 +23,24 @@ const stream = (req, res) => {
})
let range = parseRange(torrent.length, req.headers.range || '')
if (Array.isArray(range)) {
range = range[0]
res.status(206)
res
.status(206)
.set({
'Content-Range': `bytes ${range.start}-${range.end}/${torrent.length}`,
'Content-Length': range.end - range.start + 1
})
} else {
// Means that parseRange a parsing error occurred.
res.setHeader('Content-Length', torrent.length)
}
if (req.method === 'HEAD') { res.end() } else {
let stream = torrent.createReadStream(range)
const close = () => {
if (stream) {
logger.info(`Closing stream of range: ${JSON.stringify(range)} for magnet: ${magnet}`)
@ -50,27 +57,38 @@ const stream = (req, res) => {
}
}
const torrent = client.get(magnet)
// const torrent = client.get(magnet)
if (torrent) {
if (torrent.ready) {
processTorrent(torrent)
} else {
torrent.once('ready', () => processTorrent(torrent))
}
} else {
client.add(magnet, processTorrent)
}
// if (torrent) {
// if (torrent.ready) {
// processTorrent(torrent)
// } else {
// torrent.once('ready', () => processTorrent(torrent))
// }
// } else {
// client.add(magnet, processTorrent)
// }
}
const tracks = (req, res) => {
const magnet = decode(req.url.slice('/tracks/'.length))
logger.info(`Tracks for Magnet magnet: ${magnet}`)
const info = decode(req.url.slice('/tracks/'.length))
const isMagnet = /^magnet:\?/.test(info)
const type = isMagnet ? 'magnet' : 'file'
const path = isMagnet ? null : info
const magnet = isMagnet ? info : null
logger.info(`Tracks for ${type}: ${isMagnet ? magnet : path}`)
const processFile = (obj = {files: []}) => {
const { files: [torrent] } = obj
const mimeType = mime.getType(path || torrent.name)
const processTorrent = ({ files: [torrent] }) => {
const mimeType = mime.getType(torrent.name)
if (mimeType === 'video/x-matroska') {
const parser = new MatroskaSubtitles()
let stream = torrent.createReadStream()
let stream = isMagnet
? torrent.createReadStream()
: fs.createReadStream(path)
parser.once('tracks', tracks => res.sse('tracks', tracks))
@ -81,9 +99,9 @@ const tracks = (req, res) => {
const close = () => {
if (stream) {
logger.info(`Closing stream for magnet tracks: ${magnet}`)
logger.info(`Closing stream for ${type} tracks: ${magnet}`)
stream.destroy()
torrent.deselect()
torrent && torrent.deselect()
stream = null
}
}
@ -97,16 +115,20 @@ const tracks = (req, res) => {
}
}
if (magnet) {
const torrent = client.get(magnet)
if (torrent) {
if (torrent.ready) {
processTorrent(torrent)
processFile(torrent)
} else {
torrent.once('ready', () => processTorrent(torrent))
torrent.once('ready', () => processFile(torrent))
}
} else {
client.add(magnet, processTorrent)
client.add(magnet, processFile)
}
} else {
processFile()
}
}