refactor: unify video resolutions and clean up code
This commit is contained in:
parent
bf4b1da3f9
commit
df8305806f
7 changed files with 58 additions and 75 deletions
|
|
@ -51,9 +51,9 @@ def delete_converted_files(video_file_path):
|
|||
"""
|
||||
Delete all converted video files related to the original video file.
|
||||
"""
|
||||
resolutions = ["360", "720", "1080"]
|
||||
resolutions = ["360p", "720p", "1080p"]
|
||||
for resolution in resolutions:
|
||||
converted_video_path = video_file_path + f'_{resolution}p.mp4'
|
||||
converted_video_path = video_file_path + f'_{resolution}.mp4'
|
||||
converted_video_path = remove_first_mp4(converted_video_path)
|
||||
if os.path.isfile(converted_video_path):
|
||||
os.remove(converted_video_path)
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ def check_video_resolutions(request, id):
|
|||
"""
|
||||
Check if a specific video exists in different resolutions (360p, 720p, 1080p).
|
||||
"""
|
||||
resolutions = ['360', '720', '1080']
|
||||
resolutions = ['360p', '720p', '1080p']
|
||||
result = {}
|
||||
|
||||
try:
|
||||
|
|
@ -41,7 +41,7 @@ def check_video_resolutions(request, id):
|
|||
video_dir = os.path.join(settings.MEDIA_ROOT, 'videos', str(id))
|
||||
|
||||
for res in resolutions:
|
||||
video_file_name = f"{video.file_name}_{res}p.m3u8"
|
||||
video_file_name = f"{video.file_name}_{res}.m3u8"
|
||||
video_file_path = os.path.join(video_dir, video_file_name)
|
||||
result[res] = os.path.exists(video_file_path)
|
||||
|
||||
|
|
|
|||
|
|
@ -42,9 +42,9 @@ export class HeroBannerComponent implements OnChanges {
|
|||
playUrl: string = '';
|
||||
environmentBaseUrl: string = environment.baseUrl;
|
||||
movieIsUploaded: { [resolution: string]: boolean } = {
|
||||
'320': true,
|
||||
'720': true,
|
||||
'1080': true,
|
||||
'320p': true,
|
||||
'720p': true,
|
||||
'1080p': true,
|
||||
};
|
||||
constructor(
|
||||
private movieService: MovieService,
|
||||
|
|
@ -123,9 +123,9 @@ export class HeroBannerComponent implements OnChanges {
|
|||
|
||||
isAnyResolutionUploaded(): boolean {
|
||||
return (
|
||||
this.movieIsUploaded['320'] ||
|
||||
this.movieIsUploaded['720'] ||
|
||||
this.movieIsUploaded['1080']
|
||||
this.movieIsUploaded['320p'] ||
|
||||
this.movieIsUploaded['720p'] ||
|
||||
this.movieIsUploaded['1080p']
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -44,52 +44,30 @@
|
|||
</div>
|
||||
<div class="center">
|
||||
<div class="resolution-controls">
|
||||
<!-- Resolution buttons -->
|
||||
@for (resolution of availableResolutions; track $index) {
|
||||
<button
|
||||
[ngClass]="{
|
||||
'resolution-btn': true,
|
||||
active: currentResolution === '360p',
|
||||
'not-available': !movieIsUploaded['360']
|
||||
}"
|
||||
[disabled]="!movieIsUploaded['360'] || currentResolution === '360p'"
|
||||
(click)="changeResolution('360p')"
|
||||
>
|
||||
360p
|
||||
</button>
|
||||
<button
|
||||
[ngClass]="{
|
||||
'resolution-btn': true,
|
||||
active: currentResolution === '720p',
|
||||
'not-available': !movieIsUploaded['720']
|
||||
}"
|
||||
[disabled]="!movieIsUploaded['720'] || currentResolution === '720p'"
|
||||
(click)="changeResolution('720p')"
|
||||
>
|
||||
720p
|
||||
</button>
|
||||
<button
|
||||
[ngClass]="{
|
||||
'resolution-btn': true,
|
||||
active: currentResolution === '1080p',
|
||||
'not-available': !movieIsUploaded['1080']
|
||||
active: currentResolution === resolution,
|
||||
'not-available': !movieIsUploaded[resolution]
|
||||
}"
|
||||
[disabled]="
|
||||
!movieIsUploaded['1080'] || currentResolution === '1080p'
|
||||
!movieIsUploaded[resolution] || currentResolution === resolution
|
||||
"
|
||||
(click)="changeResolution('1080p')"
|
||||
(click)="changeResolution(resolution)"
|
||||
>
|
||||
1080p
|
||||
{{ resolution }}
|
||||
</button>
|
||||
}
|
||||
</div>
|
||||
<p
|
||||
*ngIf="
|
||||
!movieIsUploaded['360'] ||
|
||||
!movieIsUploaded['720'] ||
|
||||
!movieIsUploaded['1080']
|
||||
"
|
||||
>
|
||||
<!-- Resolution instructions -->
|
||||
@if (isAnyResolutionUnavailable()) {
|
||||
<p>
|
||||
(If a button cannot be selected, the video will be converted, which
|
||||
may take a few seconds.)
|
||||
</p>
|
||||
}
|
||||
</div>
|
||||
<div class="logo">
|
||||
<img src="./../../../../assets/img/logo_ci.svg" alt="Logo" />
|
||||
|
|
|
|||
|
|
@ -33,11 +33,12 @@ export class HomeComponent implements OnInit {
|
|||
playMovie: string = '';
|
||||
isLoading: boolean = true;
|
||||
uploadMovieOverview: boolean = false;
|
||||
currentResolution: '360p' | '720p' | '1080p' = '720p';
|
||||
availableResolutions: string[] = ['360p', '720p', '1080p'];
|
||||
currentResolution = '720p';
|
||||
movieIsUploaded: { [resolution: string]: boolean } = {
|
||||
'360': false,
|
||||
'720': false,
|
||||
'1080': false,
|
||||
'360p': false,
|
||||
'720p': false,
|
||||
'1080p': false,
|
||||
};
|
||||
|
||||
constructor(
|
||||
|
|
@ -98,8 +99,8 @@ export class HomeComponent implements OnInit {
|
|||
this.updateLikeMovies();
|
||||
}
|
||||
|
||||
changeResolution(resolution: '360p' | '720p' | '1080p') {
|
||||
if (this.videoPlayer && this.movieIsUploaded[resolution.replace('p', '')]) {
|
||||
changeResolution(resolution: string) {
|
||||
if (this.videoPlayer && this.movieIsUploaded[resolution]) {
|
||||
this.videoPlayer.switchResolution(resolution);
|
||||
this.currentResolution = resolution;
|
||||
}
|
||||
|
|
@ -109,6 +110,7 @@ export class HomeComponent implements OnInit {
|
|||
this.isLoading = true;
|
||||
try {
|
||||
this.movies = await this.movieService.getAllMovies();
|
||||
console.log(this.movies);
|
||||
} finally {
|
||||
this.isLoading = false;
|
||||
}
|
||||
|
|
@ -136,6 +138,12 @@ export class HomeComponent implements OnInit {
|
|||
}
|
||||
}
|
||||
|
||||
isAnyResolutionUnavailable(): boolean {
|
||||
return this.availableResolutions.some(
|
||||
(resolution) => !this.movieIsUploaded[resolution]
|
||||
);
|
||||
}
|
||||
|
||||
toggleUploadMovieOverview(value: any) {
|
||||
this.uploadMovieOverview = value;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ export class VideoPlayerComponent implements OnInit, OnDestroy {
|
|||
}
|
||||
}
|
||||
|
||||
public switchResolution(resolution: '360p' | '720p' | '1080p') {
|
||||
public switchResolution(resolution: string) {
|
||||
if (this.resolutionUrls[resolution]) {
|
||||
if (this.hls) {
|
||||
this.hls.loadSource(this.resolutionUrls[resolution]);
|
||||
|
|
|
|||
|
|
@ -1,12 +1,5 @@
|
|||
import { Injectable } from '@angular/core';
|
||||
import {
|
||||
BehaviorSubject,
|
||||
catchError,
|
||||
firstValueFrom,
|
||||
map,
|
||||
Observable,
|
||||
of,
|
||||
} from 'rxjs';
|
||||
import { catchError, firstValueFrom, map, Observable, of } from 'rxjs';
|
||||
import { ApiService } from './api.service';
|
||||
import { AuthService } from './auth.service';
|
||||
|
||||
|
|
@ -14,7 +7,10 @@ import { AuthService } from './auth.service';
|
|||
providedIn: 'root',
|
||||
})
|
||||
export class MovieService {
|
||||
private movieCache: { [key: number]: { [resolution: string]: boolean } } = {};
|
||||
private movieCache: {
|
||||
[key: number]: { [resolution: string]: boolean };
|
||||
} = {};
|
||||
private readonly availableResolutions = ['360p', '720p', '1080p'];
|
||||
|
||||
constructor(
|
||||
private apiService: ApiService,
|
||||
|
|
@ -53,35 +49,36 @@ export class MovieService {
|
|||
}
|
||||
|
||||
/**
|
||||
* Checks if a movie with the given video ID has been uploaded in the following resolutions: 360p, 720p, 1080p.
|
||||
* Check if a movie is available in all resolutions on the server.
|
||||
* This method caches the result to avoid unnecessary requests.
|
||||
*
|
||||
* @param videoID the ID of the movie to check
|
||||
* @returns an observable that emits an object with the following properties:
|
||||
* - '360': a boolean indicating whether the movie has been uploaded in 360p resolution
|
||||
* - '720': a boolean indicating whether the movie has been uploaded in 720p resolution
|
||||
* - '1080': a boolean indicating whether the movie has been uploaded in 1080p resolution
|
||||
* @returns a promise resolving to an object with the available resolutions
|
||||
* as keys and booleans indicating the availability as values.
|
||||
*/
|
||||
isMovieResolutionUploaded(
|
||||
videoID: number
|
||||
): Observable<{ [resolution: string]: boolean }> {
|
||||
const cachedRes = this.movieCache[videoID];
|
||||
if (cachedRes && Object.values(cachedRes).every(Boolean)) {
|
||||
return new BehaviorSubject(cachedRes).asObservable();
|
||||
const cachedResolutions = this.movieCache[videoID];
|
||||
|
||||
if (cachedResolutions && Object.values(cachedResolutions).every(Boolean)) {
|
||||
return of(cachedResolutions);
|
||||
}
|
||||
|
||||
return this.apiService.get(`/video/movie/${videoID}/`, true).pipe(
|
||||
map((res: any) => {
|
||||
const resolutions = {
|
||||
'360': res['360'] || false,
|
||||
'720': res['720'] || false,
|
||||
'1080': res['1080'] || false,
|
||||
};
|
||||
const resolutions = Object.fromEntries(
|
||||
this.availableResolutions.map((r) => [r, !!res[r]])
|
||||
);
|
||||
this.movieCache[videoID] = resolutions;
|
||||
return resolutions;
|
||||
}),
|
||||
catchError(() => {
|
||||
catchError((error) => {
|
||||
console.error('Failed to fetch movie resolutions', error);
|
||||
this.authService.logout();
|
||||
return of({ '360': false, '720': false, '1080': false });
|
||||
return of(
|
||||
Object.fromEntries(this.availableResolutions.map((r) => [r, false]))
|
||||
);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue