mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-07-09 03:04:20 -04:00
Creating web-app player seek-bar and volume controls.
This commit is contained in:
parent
44c8451735
commit
3ef233a1b6
@ -19,7 +19,15 @@
|
||||
</div>
|
||||
<div class="content">
|
||||
<h3>S{{this.item.seasonNumber}}:E{{this.item.episodeNumber}} - {{this.item.title}}</h3>
|
||||
<mat-progress-bar color="accent"></mat-progress-bar>
|
||||
|
||||
<div class="seek-bar">
|
||||
<div id="progress-bar">
|
||||
<div id="buffered"></div>
|
||||
<div id="progress"></div>
|
||||
</div>
|
||||
<div id="thumb"><div></div></div>
|
||||
</div>
|
||||
|
||||
<div class="buttons">
|
||||
<div class="left">
|
||||
<button *ngIf="this.item.previousEpisode" mat-icon-button data-toggle="tooltip" data-placement="top" title="Previous" routerLink="/watch/{{this.item.previousEpisode}}">
|
||||
@ -41,12 +49,15 @@
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
<button mat-icon-button data-toggle="tooltip" data-placement="top" title="Volume">
|
||||
<mat-icon>volume_up</mat-icon>
|
||||
<div id="volume">
|
||||
<button mat-icon-button data-toggle="tooltip" data-placement="top" title="Volume">
|
||||
<mat-icon>{{this.volumeIcon}}</mat-icon>
|
||||
</button>
|
||||
|
||||
<mat-slider></mat-slider>
|
||||
</button>
|
||||
<p>{{this.minutes | number: '2.0-0'}}:{{this.seconds | number: '2.0-0'}} / --:--</p>
|
||||
<mat-slider [value]="volume" (input)="changeVolume($event)"></mat-slider>
|
||||
</div>
|
||||
<p *ngIf="this.maxHours; else elseBlock">{{this.hours | number: '2.0-0'}}:{{this.minutes | number: '2.0-0'}}:{{this.seconds | number: '2.0-0'}} / {{this.maxHours | number: '2.0-0'}}:{{this.maxMinutes | number: '2.0-0'}}:{{this.maxSeconds | number: '2.0-0'}}</p>
|
||||
<ng-template #elseBlock><p>{{this.minutes | number: '2.0-0'}}:{{this.seconds | number: '2.0-0'}} / {{this.maxMinutes | number: '2.0-0'}}:{{this.maxSeconds | number: '2.0-0'}}</p></ng-template>
|
||||
</div>
|
||||
<div class="right">
|
||||
<button *ngIf="this.item.audios != null" mat-icon-button data-toggle="tooltip" data-placement="top" title="Select audio track">
|
||||
|
@ -70,14 +70,6 @@
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
> mat-progress-bar
|
||||
{
|
||||
width: 100%;
|
||||
height: 2px;
|
||||
margin-top: 1rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.buttons
|
||||
{
|
||||
display: flex;
|
||||
@ -115,6 +107,79 @@
|
||||
}
|
||||
}
|
||||
|
||||
.seek-bar
|
||||
{
|
||||
width: 100%;
|
||||
height: auto;
|
||||
padding-top: 1rem;
|
||||
padding-bottom: 1rem;
|
||||
position: relative;
|
||||
|
||||
#progress-bar
|
||||
{
|
||||
width: 100%;
|
||||
height: 4px;
|
||||
position: relative;
|
||||
background-color: rgba(255, 255, 255, .2);
|
||||
transform: scaleY(.6);
|
||||
|
||||
#progress
|
||||
{
|
||||
width: 0;
|
||||
height: 100%;
|
||||
background-color: var(--accentColor);
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
#buffered
|
||||
{
|
||||
width: 0;
|
||||
height: 100%;
|
||||
background-color: rgba(255, 255, 255, .5);
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
#thumb
|
||||
{
|
||||
width: 100%;
|
||||
height: 12px;
|
||||
position: absolute;
|
||||
left: -6px;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
margin: auto;
|
||||
opacity: 0;
|
||||
|
||||
> div
|
||||
{
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
border-radius: 6px;
|
||||
background-color: var(--accentColor);
|
||||
}
|
||||
}
|
||||
|
||||
&:hover
|
||||
{
|
||||
#progress-bar
|
||||
{
|
||||
transform: scaleY(1);
|
||||
}
|
||||
|
||||
#thumb
|
||||
{
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#nextBtn
|
||||
{
|
||||
@ -173,3 +238,38 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#volume
|
||||
{
|
||||
display: flex;
|
||||
|
||||
> button
|
||||
{
|
||||
outline: none;
|
||||
}
|
||||
|
||||
&:hover, &:focus-within
|
||||
{
|
||||
> mat-slider
|
||||
{
|
||||
width: 100px;
|
||||
}
|
||||
}
|
||||
|
||||
> mat-slider
|
||||
{
|
||||
width: 0px;
|
||||
min-width: 0px;
|
||||
padding: 0;
|
||||
height: 40px;
|
||||
overflow: hidden;
|
||||
transition: width .2s cubic-bezier(0.4,0, 1, 1);
|
||||
|
||||
&::ng-deep > div
|
||||
{
|
||||
top: 19px;
|
||||
left: 10px;
|
||||
right: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,10 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { Component, OnInit, ViewChild } from '@angular/core';
|
||||
import { WatchItem } from "../../models/watch-item";
|
||||
import { ActivatedRoute } from "@angular/router";
|
||||
import { DomSanitizer } from "@angular/platform-browser";
|
||||
import { DomSanitizer, Title } from "@angular/platform-browser";
|
||||
import { Location } from "@angular/common";
|
||||
import { MatSliderChange } from "@angular/material/slider";
|
||||
import { HtmlAstPath } from "@angular/compiler";
|
||||
|
||||
@Component({
|
||||
selector: 'app-player',
|
||||
@ -13,16 +15,26 @@ export class PlayerComponent implements OnInit
|
||||
{
|
||||
item: WatchItem;
|
||||
|
||||
volume: number = 100;
|
||||
|
||||
hours: number;
|
||||
minutes: number;
|
||||
seconds: number;
|
||||
|
||||
maxHours: number;
|
||||
maxMinutes: number;
|
||||
maxSeconds: number;
|
||||
|
||||
playIcon: string = "pause"; //Icon used by the play btn.
|
||||
volumeIcon: string = "volume_up"; //Icon used by the volume btn.
|
||||
fullscreenIcon: string = "fullscreen"; //Icon used by the fullscreen btn.
|
||||
|
||||
private player: HTMLVideoElement;
|
||||
private thumb: HTMLElement;
|
||||
private progress: HTMLElement;
|
||||
private buffered: HTMLElement;
|
||||
|
||||
constructor(private route: ActivatedRoute, private sanitizer: DomSanitizer, private location: Location) { }
|
||||
constructor(private route: ActivatedRoute, private sanitizer: DomSanitizer, private location: Location, private title: Title) { }
|
||||
|
||||
ngOnInit()
|
||||
{
|
||||
@ -30,20 +42,32 @@ export class PlayerComponent implements OnInit
|
||||
this.route.data.subscribe((data) =>
|
||||
{
|
||||
this.item = data.item;
|
||||
this.item.duration = 20 * 60;
|
||||
|
||||
if (this.player)
|
||||
{
|
||||
this.player.load();
|
||||
this.initPlayBtn();
|
||||
}
|
||||
|
||||
this.maxSeconds = Math.round(this.item.duration % 60);
|
||||
this.maxMinutes = Math.round(this.item.duration / 60 % 60);
|
||||
this.maxHours = Math.round(this.item.duration / 3600);
|
||||
|
||||
this.title.setTitle(this.item.showTitle + " S" + this.item.seasonNumber + ":E" + this.item.episodeNumber + " - Kyoo");
|
||||
});
|
||||
console.log("Init");
|
||||
}
|
||||
|
||||
ngAfterViewInit()
|
||||
{
|
||||
this.player = document.getElementById("player") as HTMLVideoElement;
|
||||
this.thumb = document.getElementById("thumb") as HTMLElement;
|
||||
this.progress = document.getElementById("progress") as HTMLElement;
|
||||
this.buffered = document.getElementById("buffered") as HTMLElement;
|
||||
this.player.controls = false;
|
||||
//console.log(this.player.volume * 100);
|
||||
//this.volume = this.player.volume * 100;
|
||||
//this.changeVolumeBtn();
|
||||
|
||||
this.player.onplay = () =>
|
||||
{
|
||||
@ -58,8 +82,18 @@ export class PlayerComponent implements OnInit
|
||||
|
||||
this.player.ontimeupdate = () =>
|
||||
{
|
||||
this.hours = Math.round(this.player.currentTime / 60 % 60);
|
||||
this.seconds = Math.round(this.player.currentTime % 60);
|
||||
this.minutes = Math.round(this.player.currentTime / 60);
|
||||
|
||||
this.thumb.style.transform = "translateX(" + (this.player.currentTime / this.item.duration * 100) + "%)";
|
||||
this.progress.style.width = (this.player.currentTime / this.item.duration * 100) + "%";
|
||||
};
|
||||
|
||||
this.player.onprogress = () =>
|
||||
{
|
||||
if (this.player.buffered.length > 0)
|
||||
this.buffered.style.width = (this.player.buffered.end(this.player.buffered.length - 1) / this.item.duration * 100) + "%";
|
||||
};
|
||||
|
||||
|
||||
@ -83,6 +117,7 @@ export class PlayerComponent implements OnInit
|
||||
ngOnDestroy()
|
||||
{
|
||||
document.getElementById("nav").classList.remove("d-none");
|
||||
this.title.setTitle("Kyoo");
|
||||
}
|
||||
|
||||
back()
|
||||
@ -112,6 +147,26 @@ export class PlayerComponent implements OnInit
|
||||
document.exitFullscreen();
|
||||
}
|
||||
|
||||
changeVolume(event: MatSliderChange)
|
||||
{
|
||||
this.player.volume = event.value / 100;
|
||||
this.volume = event.value;
|
||||
|
||||
this.changeVolumeBtn();
|
||||
}
|
||||
|
||||
changeVolumeBtn()
|
||||
{
|
||||
if (this.volume == 0)
|
||||
this.volumeIcon = "volume_off";
|
||||
else if (this.volume < 25)
|
||||
this.volumeIcon = "volume_mute";
|
||||
else if (this.volume < 65)
|
||||
this.volumeIcon = "volume_down";
|
||||
else
|
||||
this.volumeIcon = "volume_up";
|
||||
}
|
||||
|
||||
|
||||
getThumb(url: string)
|
||||
{
|
||||
|
@ -9,6 +9,7 @@ export interface WatchItem
|
||||
video: string;
|
||||
title: string;
|
||||
link: string;
|
||||
duration: number;
|
||||
releaseDate;
|
||||
|
||||
previousEpisode: string;
|
||||
|
Loading…
x
Reference in New Issue
Block a user