Add Download links to videos
This commit is contained in:
parent
5d63bb7f01
commit
5cb71a48f2
|
@ -66,6 +66,10 @@ export default Vue.extend({
|
|||
isUpcoming: {
|
||||
type: Boolean,
|
||||
required: true
|
||||
},
|
||||
downloadLinks: {
|
||||
type: Array,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data: function () {
|
||||
|
@ -99,6 +103,26 @@ export default Vue.extend({
|
|||
return this.$store.getters.getHideRecommendedVideos
|
||||
},
|
||||
|
||||
hideVideoLikesAndDislikes: function () {
|
||||
return this.$store.getters.getHideVideoLikesAndDislikes
|
||||
},
|
||||
|
||||
hideVideoViews: function () {
|
||||
return this.$store.getters.getHideVideoViews
|
||||
},
|
||||
|
||||
downloadLinkNames: function () {
|
||||
return this.downloadLinks.map((download) => {
|
||||
return download.label
|
||||
})
|
||||
},
|
||||
|
||||
downloadLinkValues: function () {
|
||||
return this.downloadLinks.map((download) => {
|
||||
return download.url
|
||||
})
|
||||
},
|
||||
|
||||
formatTypeNames: function () {
|
||||
return [
|
||||
this.$t('Change Format.Use Dash Formats').toUpperCase(),
|
||||
|
@ -153,12 +177,6 @@ export default Vue.extend({
|
|||
const dateSplit = date.toDateString().split(' ')
|
||||
const localeDateString = `Video.Published.${dateSplit[1]}`
|
||||
return `${this.$t(localeDateString)} ${dateSplit[2]}, ${dateSplit[3]}`
|
||||
},
|
||||
hideVideoLikesAndDislikes: function () {
|
||||
return this.$store.getters.getHideVideoLikesAndDislikes
|
||||
},
|
||||
hideVideoViews: function () {
|
||||
return this.$store.getters.getHideVideoViews
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
@ -252,6 +270,11 @@ export default Vue.extend({
|
|||
}
|
||||
},
|
||||
|
||||
handleDownloadLink: function (url) {
|
||||
const shell = require('electron').shell
|
||||
shell.openExternal(url)
|
||||
},
|
||||
|
||||
...mapActions([
|
||||
'showToast',
|
||||
'updateProfile'
|
||||
|
|
|
@ -67,6 +67,16 @@
|
|||
theme="secondary"
|
||||
@click="$emit('theatre-mode')"
|
||||
/>
|
||||
<ft-icon-button
|
||||
v-if="!isUpcoming && downloadLinks.length > 0"
|
||||
:title="$t('Video.Download Video')"
|
||||
class="option"
|
||||
theme="secondary"
|
||||
icon="download"
|
||||
:dropdown-names="downloadLinkNames"
|
||||
:dropdown-values="downloadLinkValues"
|
||||
@click="handleDownloadLink"
|
||||
/>
|
||||
<ft-icon-button
|
||||
v-if="!isUpcoming"
|
||||
:title="$t('Change Format.Change Video Formats')"
|
||||
|
|
|
@ -69,6 +69,7 @@ export default Vue.extend({
|
|||
audioSourceList: [],
|
||||
captionSourceList: [],
|
||||
recommendedVideos: [],
|
||||
downloadLinks: [],
|
||||
watchingPlaylist: false,
|
||||
playlistId: '',
|
||||
playNextTimeout: null
|
||||
|
@ -138,6 +139,7 @@ export default Vue.extend({
|
|||
this.activeFormat = this.defaultVideoFormat
|
||||
this.videoStoryboardSrc = ''
|
||||
this.captionSourceList = []
|
||||
this.downloadLinks = []
|
||||
|
||||
this.checkIfPlaylist()
|
||||
|
||||
|
@ -311,6 +313,27 @@ export default Vue.extend({
|
|||
this.videoLengthSeconds = parseInt(result.videoDetails.lengthSeconds)
|
||||
if (result.player_response.streamingData !== undefined) {
|
||||
this.videoSourceList = result.player_response.streamingData.formats.reverse()
|
||||
this.downloadLinks = result.formats.map((format) => {
|
||||
const qualityLabel = format.qualityLabel || format.bitrate
|
||||
const itag = format.itag
|
||||
const fps = format.fps ? (format.fps + 'fps') : 'kbps'
|
||||
const type = format.mimeType.match(/.*;/)[0].replace(';', '')
|
||||
let label = `${qualityLabel} ${fps} - ${type}`
|
||||
|
||||
if (itag !== 18 && itag !== 22) {
|
||||
if (type.includes('video')) {
|
||||
label += ` ${this.$t('Video.video only')}`
|
||||
} else {
|
||||
label += ` ${this.$t('Video.audio only')}`
|
||||
}
|
||||
}
|
||||
const object = {
|
||||
url: format.url,
|
||||
label: label
|
||||
}
|
||||
|
||||
return object
|
||||
})
|
||||
} else {
|
||||
// video might be region locked or something else. This leads to no formats being available
|
||||
this.showToast({
|
||||
|
@ -488,6 +511,28 @@ export default Vue.extend({
|
|||
this.videoLengthSeconds = result.lengthSeconds
|
||||
this.videoSourceList = result.formatStreams.reverse()
|
||||
|
||||
this.downloadLinks = result.adaptiveFormats.concat(this.videoSourceList).map((format) => {
|
||||
const qualityLabel = format.qualityLabel || format.bitrate
|
||||
const itag = parseInt(format.itag)
|
||||
const fps = format.fps ? (format.fps + 'fps') : 'kbps'
|
||||
const type = format.type.match(/.*;/)[0].replace(';', '')
|
||||
let label = `${qualityLabel} ${fps} - ${type}`
|
||||
|
||||
if (itag !== 18 && itag !== 22) {
|
||||
if (type.includes('video')) {
|
||||
label += ` ${this.$t('Video.video only')}`
|
||||
} else {
|
||||
label += ` ${this.$t('Video.audio only')}`
|
||||
}
|
||||
}
|
||||
const object = {
|
||||
url: format.url,
|
||||
label: label
|
||||
}
|
||||
|
||||
return object
|
||||
}).reverse()
|
||||
|
||||
this.audioSourceList = result.adaptiveFormats.filter((format) => {
|
||||
return format.type.includes('audio')
|
||||
}).map((format) => {
|
||||
|
|
|
@ -75,6 +75,7 @@
|
|||
:view-count="videoViewCount"
|
||||
:get-timestamp="getTimestamp"
|
||||
:is-upcoming="isUpcoming"
|
||||
:download-links="downloadLinks"
|
||||
class="watchVideo"
|
||||
:class="{ theatreWatchVideo: useTheatreMode }"
|
||||
@theatre-mode="toggleTheatreMode"
|
||||
|
|
|
@ -408,6 +408,9 @@ Video:
|
|||
'Live Chat is currently not supported with the Invidious API. A direct connection to YouTube is required.': Live
|
||||
Chat is currently not supported with the Invidious API. A direct connection to
|
||||
YouTube is required.
|
||||
Download Video: Download Video
|
||||
video only: video only
|
||||
audio only: audio only
|
||||
Audio:
|
||||
Low: Low
|
||||
Medium: Medium
|
||||
|
|
Loading…
Reference in New Issue