From 024e1fe2eb06c7d5c36c445cb7575839e9c6bd47 Mon Sep 17 00:00:00 2001 From: Preston Date: Fri, 28 Aug 2020 15:43:10 -0400 Subject: [PATCH] Add Module to generate manifest files locally --- .gitignore | 1 + package-lock.json | 17 ++++++++ package.json | 1 + src/renderer/views/Watch/Watch.js | 69 +++++++++++++++++++++++-------- 4 files changed, 71 insertions(+), 17 deletions(-) diff --git a/.gitignore b/.gitignore index 5d78d022..82b7513e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ .DS_Store dist/electron/* storyboards/* +dashFiles/* dist/web/* build/* !build/icons diff --git a/package-lock.json b/package-lock.json index ad650fb1..a9b1f0f9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20095,6 +20095,14 @@ "xtend": "^4.0.0" } }, + "xml-js": { + "version": "1.6.11", + "resolved": "https://registry.npmjs.org/xml-js/-/xml-js-1.6.11.tgz", + "integrity": "sha512-7rVi2KMfwfWFl+GpPg6m80IVMWXLRjO+PxTq7V2CDhoGak0wzYzFgUY2m4XJ47OGdXd8eLE8EmwfAmdjw7lC1g==", + "requires": { + "sax": "^1.2.4" + } + }, "xml-name-validator": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", @@ -20272,6 +20280,15 @@ "querystring": "^0.2.0" } }, + "yt-dash-manifest-generator": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/yt-dash-manifest-generator/-/yt-dash-manifest-generator-1.0.2.tgz", + "integrity": "sha512-rcBsAAhwlxtW/9irXRbU8N/8Qpft96OO0pLFvF8O7nDrjRWljnJC+DheXuhYGXpMqJGksROH1xQ1bHpwwp310g==", + "requires": { + "xml-js": "^1.6.11", + "ytdl-core": "^3.2.2" + } + }, "yt-trending-scraper": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/yt-trending-scraper/-/yt-trending-scraper-1.0.3.tgz", diff --git a/package.json b/package.json index 67df45f2..ddc904b5 100644 --- a/package.json +++ b/package.json @@ -42,6 +42,7 @@ "youtube-comments-task": "^1.3.15", "youtube-suggest": "^1.1.0", "yt-channel-info": "^1.1.0", + "yt-dash-manifest-generator": "^1.0.2", "yt-trending-scraper": "^1.0.3", "yt-xml2vtt": "^1.1.2", "ytdl-core": "^3.2.2", diff --git a/src/renderer/views/Watch/Watch.js b/src/renderer/views/Watch/Watch.js index 348db186..d0d3f435 100644 --- a/src/renderer/views/Watch/Watch.js +++ b/src/renderer/views/Watch/Watch.js @@ -4,6 +4,7 @@ import xml2vtt from 'yt-xml2vtt' import $ from 'jquery' import fs from 'fs' import electron from 'electron' +import ytDashGen from 'yt-dash-manifest-generator' import FtLoader from '../../components/ft-loader/ft-loader.vue' import FtCard from '../../components/ft-card/ft-card.vue' import FtElementList from '../../components/ft-element-list/ft-element-list.vue' @@ -55,6 +56,7 @@ export default Vue.extend({ videoPublished: 0, videoStoryboardSrc: '', audioUrl: '', + dashSrc: [], activeSourceList: [], videoSourceList: [], audioSourceList: [], @@ -139,23 +141,6 @@ export default Vue.extend({ youtubeNoCookieEmbeddedFrame: function () { return `` - }, - - dashSrc: function () { - let url = `${this.invidiousInstance}/api/manifest/dash/id/${this.videoId}.mpd` - - if (this.proxyVideos || !this.usingElectron) { - url = url + '?local=true' - } - - return [ - { - url: url, - type: 'application/dash+xml', - label: 'Dash', - qualityLabel: 'Auto' - } - ] } }, watch: { @@ -306,6 +291,7 @@ export default Vue.extend({ } else { this.videoLengthSeconds = parseInt(result.videoDetails.lengthSeconds) this.videoSourceList = result.player_response.streamingData.formats + this.dashSrc = await this.createLocalDashManifest(result.formats) this.audioSourceList = result.player_response.streamingData.adaptiveFormats.filter((format) => { return format.mimeType.includes('audio') @@ -619,6 +605,55 @@ export default Vue.extend({ } }, + createLocalDashManifest: function (formats) { + const xmlData = ytDashGen.generate_dash_file_from_formats(formats, this.videoLengthSeconds) + const userData = electron.remote.app.getPath('userData') + let fileLocation + let uriSchema + if (this.isDev) { + fileLocation = `dashFiles/${this.videoId}.xml` + uriSchema = fileLocation + // if the location does not exist, writeFileSync will not create the directory, so we have to do that manually + if (!fs.existsSync('dashFiles/')) { + fs.mkdirSync('dashFiles/') + } + } else { + fileLocation = `${userData}/dashFiles/${this.videoId}.xml` + uriSchema = `file://${fileLocation}` + + if (!fs.existsSync(`${userData}/dashFiles/`)) { + fs.mkdirSync(`${userData}/dashFiles/`) + } + } + fs.writeFileSync(fileLocation, xmlData) + console.log('CREATED FILE') + return [ + { + url: uriSchema, + type: 'application/dash+xml', + label: 'Dash', + qualityLabel: 'Auto' + } + ] + }, + + createInvidiousDashManifest: function () { + let url = `${this.invidiousInstance}/api/manifest/dash/id/${this.videoId}.mpd` + + if (this.proxyVideos || !this.usingElectron) { + url = url + '?local=true' + } + + return [ + { + url: url, + type: 'application/dash+xml', + label: 'Dash', + qualityLabel: 'Auto' + } + ] + }, + createLocalStoryboardUrls: function (templateUrl) { const storyboards = templateUrl.split('|') const storyboardArray = []