mirror of
				https://github.com/TeamPiped/Piped.git
				synced 2024-08-14 23:57:27 +00:00 
			
		
		
		
	Move player to it's own component.
Fixes a Vue specific bug, as well as captions.
This commit is contained in:
		
							parent
							
								
									06c23f8847
								
							
						
					
					
						commit
						17c351fe64
					
				
					 2 changed files with 152 additions and 158 deletions
				
			
		
							
								
								
									
										141
									
								
								src/components/Player.vue
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										141
									
								
								src/components/Player.vue
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,141 @@
 | 
				
			||||||
 | 
					<template>
 | 
				
			||||||
 | 
					    <div class="uk-container-expand">
 | 
				
			||||||
 | 
					        <div data-shaka-player-container>
 | 
				
			||||||
 | 
					            <video
 | 
				
			||||||
 | 
					                data-shaka-player
 | 
				
			||||||
 | 
					                autoplay
 | 
				
			||||||
 | 
					                style="width: 100%; height: 100%"
 | 
				
			||||||
 | 
					            ></video>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<script>
 | 
				
			||||||
 | 
					import("shaka-player/dist/controls.css");
 | 
				
			||||||
 | 
					const shaka = import("shaka-player/dist/shaka-player.ui.js");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default {
 | 
				
			||||||
 | 
					    props: {
 | 
				
			||||||
 | 
					        video: Object,
 | 
				
			||||||
 | 
					        sponsors: Object,
 | 
				
			||||||
 | 
					        selectedAutoPlay: Boolean
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    methods: {
 | 
				
			||||||
 | 
					        loadVideo() {
 | 
				
			||||||
 | 
					            const videoEl = document.querySelector("video");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            videoEl.setAttribute("poster", this.video.thumbnailUrl);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (this.$route.query.t) videoEl.currentTime = this.$route.query.t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            const noPrevPlayer = !this.player;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            var streams = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            streams.push(...this.video.audioStreams);
 | 
				
			||||||
 | 
					            streams.push(...this.video.videoStreams);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            const dash = require("@/utils/DashUtils.js").default.generate_dash_file_from_formats(
 | 
				
			||||||
 | 
					                streams,
 | 
				
			||||||
 | 
					                this.video.duration
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (noPrevPlayer)
 | 
				
			||||||
 | 
					                shaka
 | 
				
			||||||
 | 
					                    .then(shaka => shaka.default)
 | 
				
			||||||
 | 
					                    .then(shaka => {
 | 
				
			||||||
 | 
					                        this.shaka = shaka;
 | 
				
			||||||
 | 
					                        shaka.polyfill.installAll();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        const player = new shaka.Player(videoEl);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        this.player = player;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        this.setPlayerAttrs(player, videoEl, dash, shaka);
 | 
				
			||||||
 | 
					                    });
 | 
				
			||||||
 | 
					            else this.setPlayerAttrs(this.player, videoEl, dash, this.shaka);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if (noPrevPlayer) {
 | 
				
			||||||
 | 
					                videoEl.addEventListener("timeupdate", () => {
 | 
				
			||||||
 | 
					                    if (this.sponsors && this.sponsors.segments) {
 | 
				
			||||||
 | 
					                        const time = videoEl.currentTime;
 | 
				
			||||||
 | 
					                        this.sponsors.segments.map(segment => {
 | 
				
			||||||
 | 
					                            if (!segment.skipped) {
 | 
				
			||||||
 | 
					                                const end = segment.segment[1];
 | 
				
			||||||
 | 
					                                if (time >= segment.segment[0] && time < end) {
 | 
				
			||||||
 | 
					                                    console.log("Skipped segment at " + time);
 | 
				
			||||||
 | 
					                                    videoEl.currentTime = end;
 | 
				
			||||||
 | 
					                                    segment.skipped = true;
 | 
				
			||||||
 | 
					                                    return;
 | 
				
			||||||
 | 
					                                }
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                        });
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                videoEl.addEventListener("volumechange", () => {
 | 
				
			||||||
 | 
					                    if (localStorage)
 | 
				
			||||||
 | 
					                        localStorage.setItem("volume", videoEl.volume);
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                videoEl.addEventListener("ended", () => {
 | 
				
			||||||
 | 
					                    if (
 | 
				
			||||||
 | 
					                        this.selectedAutoPlay &&
 | 
				
			||||||
 | 
					                        this.video.relatedStreams.length > 0
 | 
				
			||||||
 | 
					                    )
 | 
				
			||||||
 | 
					                        this.$router.push(this.video.relatedStreams[0].url);
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            //TODO: Add sponsors on seekbar: https://github.com/ajayyy/SponsorBlock/blob/e39de9fd852adb9196e0358ed827ad38d9933e29/src/js-components/previewBar.ts#L12
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        setPlayerAttrs(player, videoEl, dash, shaka) {
 | 
				
			||||||
 | 
					            player
 | 
				
			||||||
 | 
					                .load(
 | 
				
			||||||
 | 
					                    "data:application/dash+xml;charset=utf-8;base64," +
 | 
				
			||||||
 | 
					                        btoa(dash)
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
 | 
					                .then(() => {
 | 
				
			||||||
 | 
					                    this.video.subtitles.map(subtitle => {
 | 
				
			||||||
 | 
					                        player.addTextTrack(
 | 
				
			||||||
 | 
					                            subtitle.url,
 | 
				
			||||||
 | 
					                            "eng",
 | 
				
			||||||
 | 
					                            "SUBTITLE",
 | 
				
			||||||
 | 
					                            subtitle.mimeType,
 | 
				
			||||||
 | 
					                            null,
 | 
				
			||||||
 | 
					                            "English"
 | 
				
			||||||
 | 
					                        );
 | 
				
			||||||
 | 
					                        player.setTextTrackVisibility(true);
 | 
				
			||||||
 | 
					                    });
 | 
				
			||||||
 | 
					                    if (localStorage)
 | 
				
			||||||
 | 
					                        videoEl.volume = localStorage.getItem("volume") || 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    const ui =
 | 
				
			||||||
 | 
					                        this.ui ||
 | 
				
			||||||
 | 
					                        (this.ui = new shaka.ui.Overlay(
 | 
				
			||||||
 | 
					                            player,
 | 
				
			||||||
 | 
					                            document.querySelector(
 | 
				
			||||||
 | 
					                                "div[data-shaka-player-container]"
 | 
				
			||||||
 | 
					                            ),
 | 
				
			||||||
 | 
					                            videoEl
 | 
				
			||||||
 | 
					                        ));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    const config = {
 | 
				
			||||||
 | 
					                        overflowMenuButtons: [
 | 
				
			||||||
 | 
					                            "quality",
 | 
				
			||||||
 | 
					                            "captions",
 | 
				
			||||||
 | 
					                            "playback_rate"
 | 
				
			||||||
 | 
					                        ],
 | 
				
			||||||
 | 
					                        seekBarColors: {
 | 
				
			||||||
 | 
					                            base: "rgba(255, 255, 255, 0.3)",
 | 
				
			||||||
 | 
					                            buffered: "rgba(255, 255, 255, 0.54)",
 | 
				
			||||||
 | 
					                            played: "rgb(255, 0, 0)"
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    ui.configure(config);
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
| 
						 | 
					@ -1,12 +1,11 @@
 | 
				
			||||||
<template>
 | 
					<template>
 | 
				
			||||||
    <div class="uk-container uk-container-xlarge">
 | 
					    <div class="uk-container uk-container-xlarge">
 | 
				
			||||||
        <div data-shaka-player-container>
 | 
					        <Player
 | 
				
			||||||
            <video
 | 
					            ref="videoPlayer"
 | 
				
			||||||
                data-shaka-player
 | 
					            :video="video"
 | 
				
			||||||
                autoplay
 | 
					            :sponsors="sponsors"
 | 
				
			||||||
                style="width: 100%; height: 100%"
 | 
					            :selectedAutoPlay="selectedAutoPlay"
 | 
				
			||||||
            ></video>
 | 
					        />
 | 
				
			||||||
        </div>
 | 
					 | 
				
			||||||
        <h1 class="uk-text-bold">{{ video.title }}</h1>
 | 
					        <h1 class="uk-text-bold">{{ video.title }}</h1>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        <img :src="video.uploaderAvatar" loading="lazy" />
 | 
					        <img :src="video.uploaderAvatar" loading="lazy" />
 | 
				
			||||||
| 
						 | 
					@ -79,10 +78,8 @@
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<script>
 | 
					<script>
 | 
				
			||||||
import "shaka-player/dist/shaka-player.ui.js";
 | 
					 | 
				
			||||||
import("shaka-player/dist/controls.css");
 | 
					 | 
				
			||||||
const shaka = import("shaka-player/dist/shaka-player.ui.js");
 | 
					 | 
				
			||||||
import Constants from "@/Constants.js";
 | 
					import Constants from "@/Constants.js";
 | 
				
			||||||
 | 
					import Player from "@/components/Player.vue";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default {
 | 
					export default {
 | 
				
			||||||
    name: "App",
 | 
					    name: "App",
 | 
				
			||||||
| 
						 | 
					@ -145,51 +142,6 @@ export default {
 | 
				
			||||||
            if (localStorage)
 | 
					            if (localStorage)
 | 
				
			||||||
                localStorage.setItem("autoplay", this.selectedAutoPlay);
 | 
					                localStorage.setItem("autoplay", this.selectedAutoPlay);
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        setPlayerAttrs(player, videoEl, dash, shaka) {
 | 
					 | 
				
			||||||
            player
 | 
					 | 
				
			||||||
                .load(
 | 
					 | 
				
			||||||
                    "data:application/dash+xml;charset=utf-8;base64," +
 | 
					 | 
				
			||||||
                        btoa(dash)
 | 
					 | 
				
			||||||
                )
 | 
					 | 
				
			||||||
                .then(() => {
 | 
					 | 
				
			||||||
                    this.video.subtitles.map(subtitle => {
 | 
					 | 
				
			||||||
                        player.addTextTrack(
 | 
					 | 
				
			||||||
                            subtitle.url,
 | 
					 | 
				
			||||||
                            "eng",
 | 
					 | 
				
			||||||
                            "SUBTITLE",
 | 
					 | 
				
			||||||
                            subtitle.mimeType,
 | 
					 | 
				
			||||||
                            null,
 | 
					 | 
				
			||||||
                            "English"
 | 
					 | 
				
			||||||
                        );
 | 
					 | 
				
			||||||
                        player.setTextTrackVisibility(true);
 | 
					 | 
				
			||||||
                    });
 | 
					 | 
				
			||||||
                    if (localStorage)
 | 
					 | 
				
			||||||
                        videoEl.volume = localStorage.getItem("volume") || 1;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    const ui =
 | 
					 | 
				
			||||||
                        window.ui ||
 | 
					 | 
				
			||||||
                        (window.ui = new shaka.ui.Overlay(
 | 
					 | 
				
			||||||
                            player,
 | 
					 | 
				
			||||||
                            document.querySelector(
 | 
					 | 
				
			||||||
                                "div[data-shaka-player-container]"
 | 
					 | 
				
			||||||
                            ),
 | 
					 | 
				
			||||||
                            videoEl
 | 
					 | 
				
			||||||
                        ));
 | 
					 | 
				
			||||||
                    const config = {
 | 
					 | 
				
			||||||
                        overflowMenuButtons: [
 | 
					 | 
				
			||||||
                            "quality",
 | 
					 | 
				
			||||||
                            "captions",
 | 
					 | 
				
			||||||
                            "playback_rate"
 | 
					 | 
				
			||||||
                        ],
 | 
					 | 
				
			||||||
                        seekBarColors: {
 | 
					 | 
				
			||||||
                            base: "rgba(255, 255, 255, 0.3)",
 | 
					 | 
				
			||||||
                            buffered: "rgba(255, 255, 255, 0.54)",
 | 
					 | 
				
			||||||
                            played: "rgb(255, 0, 0)"
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                    };
 | 
					 | 
				
			||||||
                    ui.configure(config);
 | 
					 | 
				
			||||||
                });
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        async getVideoData() {
 | 
					        async getVideoData() {
 | 
				
			||||||
            this.fetchVideo()
 | 
					            this.fetchVideo()
 | 
				
			||||||
                .then(data => {
 | 
					                .then(data => {
 | 
				
			||||||
| 
						 | 
					@ -203,115 +155,16 @@ export default {
 | 
				
			||||||
                        .replaceAll("https://www.youtube.com", "")
 | 
					                        .replaceAll("https://www.youtube.com", "")
 | 
				
			||||||
                        .replaceAll("\n", "<br>");
 | 
					                        .replaceAll("\n", "<br>");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    const noPrevPlayer = !window.player;
 | 
					                    this.$refs.videoPlayer.loadVideo();
 | 
				
			||||||
 | 
					 | 
				
			||||||
                    var streams = [];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    streams.push(...this.video.audioStreams);
 | 
					 | 
				
			||||||
                    streams.push(...this.video.videoStreams);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    const dash = require("../utils/DashUtils.js").default.generate_dash_file_from_formats(
 | 
					 | 
				
			||||||
                        streams,
 | 
					 | 
				
			||||||
                        this.video.duration
 | 
					 | 
				
			||||||
                    );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    const WatchVideo = this;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    const videoEl = document.querySelector("video");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    setTimeout(function() {
 | 
					 | 
				
			||||||
                        shaka
 | 
					 | 
				
			||||||
                            .then(shaka => shaka.default)
 | 
					 | 
				
			||||||
                            .then(shaka => {
 | 
					 | 
				
			||||||
                                if (noPrevPlayer) {
 | 
					 | 
				
			||||||
                                    shaka.polyfill.installAll();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                                    const player = new shaka.Player(videoEl);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                                    WatchVideo.player = player;
 | 
					 | 
				
			||||||
                                    window.player = player;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                                    WatchVideo.setPlayerAttrs(
 | 
					 | 
				
			||||||
                                        player,
 | 
					 | 
				
			||||||
                                        videoEl,
 | 
					 | 
				
			||||||
                                        dash,
 | 
					 | 
				
			||||||
                                        shaka
 | 
					 | 
				
			||||||
                                    );
 | 
					 | 
				
			||||||
                                } else {
 | 
					 | 
				
			||||||
                                    WatchVideo.setPlayerAttrs(
 | 
					 | 
				
			||||||
                                        window.player,
 | 
					 | 
				
			||||||
                                        videoEl,
 | 
					 | 
				
			||||||
                                        dash,
 | 
					 | 
				
			||||||
                                        shaka
 | 
					 | 
				
			||||||
                                    );
 | 
					 | 
				
			||||||
                                }
 | 
					 | 
				
			||||||
                            });
 | 
					 | 
				
			||||||
                    }, 0);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    videoEl.setAttribute("poster", this.video.thumbnailUrl);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    if (this.$route.query.t)
 | 
					 | 
				
			||||||
                        videoEl.currentTime = this.$route.query.t;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    videoEl.addEventListener("loadedmetadata", function() {
 | 
					 | 
				
			||||||
                        const track = this.addTextTrack(
 | 
					 | 
				
			||||||
                            "captions",
 | 
					 | 
				
			||||||
                            "English",
 | 
					 | 
				
			||||||
                            "en"
 | 
					 | 
				
			||||||
                        );
 | 
					 | 
				
			||||||
                        track.mode = "showing";
 | 
					 | 
				
			||||||
                    });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    if (noPrevPlayer) {
 | 
					 | 
				
			||||||
                        videoEl.addEventListener("timeupdate", () => {
 | 
					 | 
				
			||||||
                            if (
 | 
					 | 
				
			||||||
                                WatchVideo.sponsors &&
 | 
					 | 
				
			||||||
                                WatchVideo.sponsors.segments
 | 
					 | 
				
			||||||
                            ) {
 | 
					 | 
				
			||||||
                                const time = videoEl.currentTime;
 | 
					 | 
				
			||||||
                                WatchVideo.sponsors.segments.map(segment => {
 | 
					 | 
				
			||||||
                                    if (!segment.skipped) {
 | 
					 | 
				
			||||||
                                        const end = segment.segment[1];
 | 
					 | 
				
			||||||
                                        if (
 | 
					 | 
				
			||||||
                                            time >= segment.segment[0] &&
 | 
					 | 
				
			||||||
                                            time < end
 | 
					 | 
				
			||||||
                                        ) {
 | 
					 | 
				
			||||||
                                            console.log(
 | 
					 | 
				
			||||||
                                                "Skipped segment at " + time
 | 
					 | 
				
			||||||
                                            );
 | 
					 | 
				
			||||||
                                            videoEl.currentTime = end;
 | 
					 | 
				
			||||||
                                            segment.skipped = true;
 | 
					 | 
				
			||||||
                                            return;
 | 
					 | 
				
			||||||
                                        }
 | 
					 | 
				
			||||||
                                    }
 | 
					 | 
				
			||||||
                                });
 | 
					 | 
				
			||||||
                            }
 | 
					 | 
				
			||||||
                        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                        videoEl.addEventListener("volumechange", () => {
 | 
					 | 
				
			||||||
                            if (localStorage)
 | 
					 | 
				
			||||||
                                localStorage.setItem("volume", videoEl.volume);
 | 
					 | 
				
			||||||
                        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                        videoEl.addEventListener("ended", () => {
 | 
					 | 
				
			||||||
                            if (
 | 
					 | 
				
			||||||
                                WatchVideo.selectedAutoPlay &&
 | 
					 | 
				
			||||||
                                WatchVideo.video.relatedStreams.length > 0
 | 
					 | 
				
			||||||
                            )
 | 
					 | 
				
			||||||
                                WatchVideo.$router.push(
 | 
					 | 
				
			||||||
                                    WatchVideo.video.relatedStreams[0].url
 | 
					 | 
				
			||||||
                                );
 | 
					 | 
				
			||||||
                        });
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    //const parent = this.player.el().querySelector(".vjs-progress-holder")
 | 
					 | 
				
			||||||
                    //TODO: Add sponsors on seekbar: https://github.com/ajayyy/SponsorBlock/blob/e39de9fd852adb9196e0358ed827ad38d9933e29/src/js-components/previewBar.ts#L12
 | 
					 | 
				
			||||||
                });
 | 
					                });
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        async getSponsors() {
 | 
					        async getSponsors() {
 | 
				
			||||||
            if (!localStorage || localStorage.getItem("sponsorblock") !== false)
 | 
					            if (!localStorage || localStorage.getItem("sponsorblock") !== false)
 | 
				
			||||||
                this.fetchSponsors().then(data => (this.sponsors = data));
 | 
					                this.fetchSponsors().then(data => (this.sponsors = data));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    components: {
 | 
				
			||||||
 | 
					        Player
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue