diff --git a/backend/videoflix/content/models.py b/backend/videoflix/content/models.py
index b733a01..5fab122 100644
--- a/backend/videoflix/content/models.py
+++ b/backend/videoflix/content/models.py
@@ -9,8 +9,7 @@ class Video(models.Model):
film_genre = models.CharField(max_length=20, choices=FILM_GENRES, blank=True, null=True)
video_file = models.FileField(upload_to='videos/', blank=True, null=True)
file_name = models.CharField(max_length=50, blank=True, null=True)
- thumbnail_created = models.BooleanField(default=False)
-
+
def __str__(self):
return f'({self.id}) {self.title}'
diff --git a/backend/videoflix/content/signals.py b/backend/videoflix/content/signals.py
index 506b686..623d407 100644
--- a/backend/videoflix/content/signals.py
+++ b/backend/videoflix/content/signals.py
@@ -1,5 +1,5 @@
from .models import Video
-from .tasks import convert_video_to_hls, create_thumbnails, delete_original_video, update_thumbnail_status
+from .tasks import convert_video_to_hls, create_thumbnails, delete_original_video
from django.dispatch import receiver
from django.db.models.signals import post_save, post_delete
from django.conf import settings
@@ -13,18 +13,31 @@ def video_post_save(sender, instance, created, **kwargs):
Generates a thumbnail for a newly created `Video` instance.
"""
if created:
- queue = django_rq.get_queue("default", autocommit=True)
-
#Create thumbnail
- queue.enqueue(create_thumbnails, instance, instance.id)
+ create_thumbnails(instance, instance.id)
#Convert video
for resolution in ["480", "720", "1080"]:
- queue.enqueue(convert_video_to_hls, instance.video_file.path, resolution, instance.id)
+ convert_video_to_hls(instance.video_file.path, resolution, instance.id)
# Delete the original video file
+ delete_original_video(instance.video_file.path)
+
+ """
+ # With Django RQ Worker (My server is too slow for it)
+ if created:
+ queue = django_rq.get_queue("default", autocommit=True)
+
+ Create thumbnail
+ queue.enqueue(create_thumbnails, instance, instance.id)
+
+ Convert video
+ for resolution in ["480", "720", "1080"]:
+ #queue.enqueue(convert_video_to_hls, instance.video_file.path, resolution, #instance.id)
+
+ Delete the original video file
queue.enqueue(delete_original_video, instance.video_file.path)
-
+ """
@receiver(post_delete, sender=Video)
def auto_delete_file_on_delete(sender, instance, **kwargs):
"""
diff --git a/backend/videoflix/content/tasks.py b/backend/videoflix/content/tasks.py
index 6231f50..7ec0ed7 100644
--- a/backend/videoflix/content/tasks.py
+++ b/backend/videoflix/content/tasks.py
@@ -56,16 +56,6 @@ def create_thumbnails(instance, model_id):
# Generate the thumbnails
ffmpeg.input(video_file_path, ss=1).output(thumbnail_1080p_path, vf='scale=1920:-1', vframes=1).run(overwrite_output=True)
ffmpeg.input(video_file_path, ss=1).output(thumbnail_480_path, vf='scale=720:-1', vframes=1).run(overwrite_output=True)
- # Update thumbnail status
- update_thumbnail_status(model_id)
except ffmpeg._run.Error as e:
- print(f"Ein Fehler ist aufgetreten: {e.stderr.decode()}")
-
-def update_thumbnail_status(video_id):
- try:
- video = Video.objects.get(id=video_id)
- video.thumbnail_created = True
- video.save()
- except Video.DoesNotExist:
- print(f"Video with id {video_id} does not exist.")
\ No newline at end of file
+ print(f"Ein Fehler ist aufgetreten: {e.stderr.decode()}")
\ No newline at end of file
diff --git a/frontend/src/app/components/home/browse/hero-banner/hero-banner.component.ts b/frontend/src/app/components/home/browse/hero-banner/hero-banner.component.ts
index d59f4e3..d822694 100644
--- a/frontend/src/app/components/home/browse/hero-banner/hero-banner.component.ts
+++ b/frontend/src/app/components/home/browse/hero-banner/hero-banner.component.ts
@@ -28,8 +28,4 @@ export class HeroBannerComponent {
playMovieId(videoPath: string) {
this.playMovie.emit(videoPath);
}
-
- getImagePath(): any {
- return '123';
- }
}
diff --git a/frontend/src/app/components/home/browse/upload-movie/upload-movie.component.html b/frontend/src/app/components/home/browse/upload-movie/upload-movie.component.html
index cd1b49a..a2d0352 100644
--- a/frontend/src/app/components/home/browse/upload-movie/upload-movie.component.html
+++ b/frontend/src/app/components/home/browse/upload-movie/upload-movie.component.html
@@ -92,3 +92,8 @@
+@if(movieData.send){
+
+}
diff --git a/frontend/src/app/components/home/browse/upload-movie/upload-movie.component.ts b/frontend/src/app/components/home/browse/upload-movie/upload-movie.component.ts
index 717516d..4d12e74 100644
--- a/frontend/src/app/components/home/browse/upload-movie/upload-movie.component.ts
+++ b/frontend/src/app/components/home/browse/upload-movie/upload-movie.component.ts
@@ -4,11 +4,17 @@ import { FormsModule, NgForm } from '@angular/forms';
import { ErrorService } from '../../../../services/error.service';
import { BtnLargeComponent } from '../../../../shared/components/buttons/btn-large/btn-large.component';
import { MovieService } from '../../../../services/movie.service';
+import { LoadingDialogComponent } from '../../../../shared/components/loading-dialog/loading-dialog.component';
@Component({
selector: 'app-upload-movie',
standalone: true,
- imports: [CommonModule, FormsModule, BtnLargeComponent],
+ imports: [
+ CommonModule,
+ FormsModule,
+ BtnLargeComponent,
+ LoadingDialogComponent,
+ ],
templateUrl: './upload-movie.component.html',
styleUrl: './upload-movie.component.scss',
})
@@ -48,15 +54,8 @@ export class UploadMovieComponent {
try {
this.movieData.send = true;
-
- const formData = this.createFormData();
- const response = await this.movieService
- .uploadMovie(formData)
- .toPromise();
- const videoId = response.id;
-
- await this.waitForThumbnailCreation(videoId);
-
+ let formData = this.createFormData();
+ await this.movieService.uploadMovie(formData);
ngForm.resetForm();
this.uploadMovieOverview();
this.movieData.send = false;
@@ -77,14 +76,4 @@ export class UploadMovieComponent {
}
return formData;
}
-
- private async waitForThumbnailCreation(videoId: number) {
- while (true) {
- const statusResponse = await this.movieService
- .checkThumbnailStatus(videoId)
- .toPromise();
- if (statusResponse?.thumbnail_created) break;
- await new Promise((resolve) => setTimeout(resolve, 2000));
- }
- }
}
diff --git a/frontend/src/app/environments/environment.ts b/frontend/src/app/environments/environment.ts
index eb946eb..81c24e7 100644
--- a/frontend/src/app/environments/environment.ts
+++ b/frontend/src/app/environments/environment.ts
@@ -1,7 +1,7 @@
export const environment = {
// Development
- // baseUrl: 'http://127.0.0.1:8000',
+ baseUrl: 'http://127.0.0.1:8000',
// Live
- baseUrl: 'https://videoflix-django.andre-kempf.com',
+ // baseUrl: 'https://videoflix-django.andre-kempf.com',
};
diff --git a/frontend/src/app/services/movie.service.ts b/frontend/src/app/services/movie.service.ts
index a2c12a6..9a74678 100644
--- a/frontend/src/app/services/movie.service.ts
+++ b/frontend/src/app/services/movie.service.ts
@@ -21,23 +21,10 @@ export class MovieService {
return lastValueFrom(this.http.get(url, { headers }));
}
- uploadMovie(formData: FormData): Observable {
+ uploadMovie(formData: FormData) {
+ const url = environment.baseUrl + '/content/upload/';
const headers = this.getAuthHeaders();
- return this.http.post(
- `${environment.baseUrl}/content/upload/`,
- formData,
- { headers }
- );
- }
-
- checkThumbnailStatus(
- videoId: number
- ): Observable<{ thumbnail_created: boolean }> {
- const headers = this.getAuthHeaders();
- return this.http.get<{ thumbnail_created: boolean }>(
- `${environment.baseUrl}/content/${videoId}/status/`,
- { headers }
- );
+ return lastValueFrom(this.http.post(url, formData, { headers }));
}
private getAuthHeaders(): HttpHeaders {
diff --git a/frontend/src/app/shared/components/loading-dialog/loading-dialog.component.html b/frontend/src/app/shared/components/loading-dialog/loading-dialog.component.html
new file mode 100644
index 0000000..2b811b5
--- /dev/null
+++ b/frontend/src/app/shared/components/loading-dialog/loading-dialog.component.html
@@ -0,0 +1,8 @@
+
diff --git a/frontend/src/app/shared/components/loading-dialog/loading-dialog.component.scss b/frontend/src/app/shared/components/loading-dialog/loading-dialog.component.scss
new file mode 100644
index 0000000..7666235
--- /dev/null
+++ b/frontend/src/app/shared/components/loading-dialog/loading-dialog.component.scss
@@ -0,0 +1,58 @@
+@import "./../../../../assets/style/colors.scss";
+
+.loading-dialog {
+ position: fixed;
+ top: 0;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ width: 100vw;
+ height: 100vh;
+ backdrop-filter: blur(5px);
+ background-color: rgba($black, 0.2);
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ z-index: 999;
+}
+
+.loading-content {
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+}
+
+.loader {
+ border: 6px solid $white;
+ border-top: 6px solid $blue;
+ border-radius: 50%;
+ width: 60px;
+ height: 60px;
+ animation: spin 1.5s linear infinite;
+ box-shadow: 0px 0px 15px rgba($blue, 0.5);
+ margin-bottom: 20px;
+}
+
+.loading-text {
+ text-align: center;
+ max-width: 300px;
+ padding: 12px;
+ color: $white;
+ text-shadow: 3px 3px 3px $black;
+
+ p {
+ font-size: 21px;
+ font-weight: 400;
+ margin-bottom: 6px;
+ }
+}
+
+@keyframes spin {
+ 0% {
+ transform: rotate(0deg);
+ }
+ 100% {
+ transform: rotate(360deg);
+ }
+}
diff --git a/frontend/src/app/shared/components/loading-dialog/loading-dialog.component.spec.ts b/frontend/src/app/shared/components/loading-dialog/loading-dialog.component.spec.ts
new file mode 100644
index 0000000..eb04690
--- /dev/null
+++ b/frontend/src/app/shared/components/loading-dialog/loading-dialog.component.spec.ts
@@ -0,0 +1,23 @@
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+
+import { LoadingDialogComponent } from './loading-dialog.component';
+
+describe('LoadingDialogComponent', () => {
+ let component: LoadingDialogComponent;
+ let fixture: ComponentFixture;
+
+ beforeEach(async () => {
+ await TestBed.configureTestingModule({
+ imports: [LoadingDialogComponent]
+ })
+ .compileComponents();
+
+ fixture = TestBed.createComponent(LoadingDialogComponent);
+ component = fixture.componentInstance;
+ fixture.detectChanges();
+ });
+
+ it('should create', () => {
+ expect(component).toBeTruthy();
+ });
+});
diff --git a/frontend/src/app/shared/components/loading-dialog/loading-dialog.component.ts b/frontend/src/app/shared/components/loading-dialog/loading-dialog.component.ts
new file mode 100644
index 0000000..f10b965
--- /dev/null
+++ b/frontend/src/app/shared/components/loading-dialog/loading-dialog.component.ts
@@ -0,0 +1,12 @@
+import { Component, Input } from '@angular/core';
+
+@Component({
+ selector: 'app-loading-dialog',
+ standalone: true,
+ imports: [],
+ templateUrl: './loading-dialog.component.html',
+ styleUrl: './loading-dialog.component.scss',
+})
+export class LoadingDialogComponent {
+ @Input() loadingMsg: string = '';
+}