From 0a68afe54b8f314fd79e860960a8f83354fb5a75 Mon Sep 17 00:00:00 2001 From: mauriceoegerli Date: Tue, 20 Oct 2020 17:50:58 +0200 Subject: [PATCH 01/31] =?UTF-8?q?=E2=9C=A8=20re-enable=20quality=20selecti?= =?UTF-8?q?on?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../videoplayer/QualitySelection.vue | 36 +++++++++++++++---- client/components/videoplayer/VideoPlayer.vue | 9 ++--- 2 files changed, 32 insertions(+), 13 deletions(-) diff --git a/client/components/videoplayer/QualitySelection.vue b/client/components/videoplayer/QualitySelection.vue index 9e8aca02b..84b961cd2 100644 --- a/client/components/videoplayer/QualitySelection.vue +++ b/client/components/videoplayer/QualitySelection.vue @@ -3,7 +3,7 @@
-
+
Automatic quality
- Legacy format + Video Quality
{{ quality.qualityLabel }} @@ -51,7 +51,7 @@ export default Vue.extend({ }, props: { formatStreams: Array, - adaptiveFormats: Array + adaptiveFormats: { type: Array, required: false, default: null } }, data: () => ({ qualityUrl: null, @@ -66,6 +66,9 @@ export default Vue.extend({ minAdaptiveQuality(): any { return this.sortedAdaptiveQualities[0]; }, + formatQualities(): any { + return this.formatStreams.filter(el => el.qualityLabel); + }, sortedAdaptiveQualities(): any { return this.adaptiveVideos.slice().sort((a, b) => parseInt(a.bitrate) - parseInt(b.bitrate)); }, @@ -128,6 +131,25 @@ export default Vue.extend({ box-shadow: $max-shadow; padding: 10px 0; + @media screen and (max-width: $mobile-width) { + position: fixed; + left: 0; + top: 0; + width: 100%; + max-height: 220px; + + &::after { + content: ''; + display: block; + position: fixed; + background-color: #000; + top: 0; + left: 0; + right: 0; + bottom: 0; + } + } + .quality-submenu { width: 240px; border-radius: 0; diff --git a/client/components/videoplayer/VideoPlayer.vue b/client/components/videoplayer/VideoPlayer.vue index 2b4acd638..fa5bb7701 100644 --- a/client/components/videoplayer/VideoPlayer.vue +++ b/client/components/videoplayer/VideoPlayer.vue @@ -186,10 +186,7 @@
- + Date: Wed, 21 Oct 2020 09:35:56 +0200 Subject: [PATCH 02/31] =?UTF-8?q?=E2=9C=A8=20initial=20mediaSession=20supp?= =?UTF-8?q?ort?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- client/components/videoplayer/VideoPlayer.vue | 76 +++++++++++-------- .../videoplayer/videoPlayerHelper.ts | 27 +++++++ client/store/index.ts | 4 +- scripts/no-master.sh | 0 4 files changed, 74 insertions(+), 33 deletions(-) create mode 100644 client/components/videoplayer/videoPlayerHelper.ts mode change 100644 => 100755 scripts/no-master.sh diff --git a/client/components/videoplayer/VideoPlayer.vue b/client/components/videoplayer/VideoPlayer.vue index fa5bb7701..3c853a48e 100644 --- a/client/components/videoplayer/VideoPlayer.vue +++ b/client/components/videoplayer/VideoPlayer.vue @@ -235,6 +235,7 @@ import QualitySelection from '@/components/videoplayer/QualitySelection.vue'; import SeekbarPreview from '@/components/videoplayer/SeekbarPreview.vue'; import Commons from '@/plugins/commons.ts'; import Vue from 'vue'; +import { VideoPlayerHelper } from './videoPlayerHelper'; export default Vue.extend({ name: 'Videoplayer', @@ -262,37 +263,40 @@ export default Vue.extend({ mini: Boolean, autoplay: Boolean }, - data: () => ({ - loading: true, - fullscreen: false, - commons: Commons, - dashPlayer: null, - playerOverlay: { - visible: false, - timeout: undefined, - updateInterval: undefined, - thumbnailVisible: true - }, - videoElement: { - positionSaveInterval: undefined, - buffering: true, - playing: false, - progress: 0, - progressPercentage: 0, - loadingPercentage: 0, - firstTimeBuffering: true, - aspectRatio: 16 / 9, - playerVolume: 1, - zoomed: false - }, - seekbar: { - seeking: false, - seekPercentage: 0, - hoverPercentage: 0, - hoverTime: '00:00', - hoverTimeStamp: 0 - } - }), + data() { + return { + loading: true, + fullscreen: false, + commons: Commons, + dashPlayer: null, + playerOverlay: { + visible: false, + timeout: undefined, + updateInterval: undefined, + thumbnailVisible: true + }, + videoElement: { + positionSaveInterval: undefined, + buffering: true, + playing: false, + progress: 0, + progressPercentage: 0, + loadingPercentage: 0, + firstTimeBuffering: true, + aspectRatio: 16 / 9, + playerVolume: 1, + zoomed: false + }, + seekbar: { + seeking: false, + seekPercentage: 0, + hoverPercentage: 0, + hoverTime: '00:00', + hoverTimeStamp: 0 + }, + videoPlayerHelper: new VideoPlayerHelper(this.video) + }; + }, computed: { highestVideoQuality(): string { if (this.video.formatStreams) { @@ -399,11 +403,17 @@ export default Vue.extend({ this.playerOverlay.thumbnailVisible = false; this.videoElement.playing = true; this.videoElement.positionSaveInterval = setInterval(() => this.saveVideoPosition(), 5000); + if ('mediaSession' in navigator) { + (navigator as any).mediaSession.playbackState = 'playing'; + } }, onVideoPaused() { this.videoElement.playing = false; this.saveVideoPosition(); clearInterval(this.videoElement.positionSaveInterval); + if ('mediaSession' in navigator) { + (navigator as any).mediaSession.playbackState = 'paused'; + } }, onVideoCanplay() { if (this.$refs.video && this.videoElement.firstTimeBuffering) { @@ -414,6 +424,10 @@ export default Vue.extend({ if (this.autoplay) { this.$refs.video.play(); } + if ('mediaSession' in navigator && process.browser) { + const metadata = this.videoPlayerHelper.createMediaMetadata(); + (navigator as any).mediaSession.metadata = metadata; + } } this.videoElement.buffering = false; }, diff --git a/client/components/videoplayer/videoPlayerHelper.ts b/client/components/videoplayer/videoPlayerHelper.ts new file mode 100644 index 000000000..99b2ffee9 --- /dev/null +++ b/client/components/videoplayer/videoPlayerHelper.ts @@ -0,0 +1,27 @@ +export class VideoPlayerHelper { + constructor(video: any) { + this.video = video; + } + + video: any; + + createMediaMetadata() { + // @ts-ignore + // eslint-disable-next-line no-undef + return new MediaMetadata({ + title: this.video.title, + artist: this.video.author, + artwork: this.generateArtworkUrl() + } as any); + } + + generateArtworkUrl() { + return this.video.videoThumbnails.map((el: { url: string; height: number; width: number }) => { + return { + src: el.url, + sizes: `${el.height}x${el.width}`, + type: 'image/jpg' + }; + }); + } +} diff --git a/client/store/index.ts b/client/store/index.ts index b18e3a027..604559056 100644 --- a/client/store/index.ts +++ b/client/store/index.ts @@ -23,9 +23,9 @@ export const actions = actionTree( apiUrl: process.env.VIEWTUBE_API_URL, vapidKey: process.env.VIEWTUBE_PUBLIC_VAPID, nodeEnv: process.env.NODE_ENV, - host: process.env.HOST || 'localhost', + host: process.env.HOST || '192.168.178.21', port: process.env.PORT || 8066, - baseUrl: process.env.BASE_URL || 'http://localhost:8066' + baseUrl: process.env.BASE_URL || 'http://192.168.178.21:8066' }); nuxtContext.app.$accessor.user.getUser(); if (_vuexContext.getters['instances/instances'].length === 0) { diff --git a/scripts/no-master.sh b/scripts/no-master.sh old mode 100644 new mode 100755 From 1a8c3c9036b1db489a5a3f0727031682b140f9bf Mon Sep 17 00:00:00 2001 From: mauriceoegerli Date: Wed, 21 Oct 2020 17:59:49 +0200 Subject: [PATCH 03/31] shared dto folder, videoplayer composition api --- client/components/videoplayer/VideoPlayer.vue | 389 ++++++++++-------- .../components/videoplayer/helpers/index.ts | 30 ++ .../mediaMetadata.ts} | 12 +- client/plugins/shared.ts | 2 + client/store/videoProgress.ts | 2 +- nuxt.config.js | 8 +- package.json | 2 +- .../channels/dto/channel-basic-info.dto.ts | 2 +- server/core/channels/dto/channel.dto.ts | 2 +- .../schemas/channel-basic-info.schema.ts | 2 +- server/core/common.ts | 4 +- .../playlists/dto/playlist-basic-info.dto.ts | 2 +- .../core/playlists/dto/preview-video.dto.ts | 2 +- .../core/videos/dto/video-basic-info.dto.ts | 2 +- .../videos/schemas/video-basic-info.schema.ts | 2 +- server/core/videos/schemas/video.schema.ts | 8 +- server/core/videos/video.entity.ts | 8 +- server/core/videos/videos.controller.ts | 2 +- server/core/videos/videos.service.ts | 2 +- .../dto/video}/author-thumbnail.dto.ts | 0 .../dto/video}/recommended-video.dto.ts | 0 .../dto/video}/video-thumbnail.dto.ts | 0 .../dto => shared/dto/video}/video.dto.ts | 4 +- shared/index.ts | 6 + tsconfig.eslint.json | 1 + tsconfig.json | 5 +- yarn.lock | 11 +- 27 files changed, 301 insertions(+), 209 deletions(-) create mode 100644 client/components/videoplayer/helpers/index.ts rename client/components/videoplayer/{videoPlayerHelper.ts => helpers/mediaMetadata.ts} (62%) create mode 100644 client/plugins/shared.ts rename {server/core/videos/dto => shared/dto/video}/author-thumbnail.dto.ts (100%) rename {server/core/videos/dto => shared/dto/video}/recommended-video.dto.ts (100%) rename {server/core/videos/dto => shared/dto/video}/video-thumbnail.dto.ts (100%) rename {server/core/videos/dto => shared/dto/video}/video.dto.ts (93%) create mode 100644 shared/index.ts diff --git a/client/components/videoplayer/VideoPlayer.vue b/client/components/videoplayer/VideoPlayer.vue index 3c853a48e..71f1e6ac1 100644 --- a/client/components/videoplayer/VideoPlayer.vue +++ b/client/components/videoplayer/VideoPlayer.vue @@ -1,6 +1,6 @@