Make video loading dynamic.

This commit is contained in:
Florian THIERRY
2026-07-24 15:38:36 +02:00
parent cef96884c6
commit b6ab469616
4 changed files with 30 additions and 16 deletions
+1 -1
View File
@@ -28,7 +28,6 @@ pub async fn get_video_stream(
) -> impl Responder { ) -> impl Responder {
let video_result = video_service.get_video_stream(video_id.into_inner()); let video_result = video_service.get_video_stream(video_id.into_inner());
match video_result { match video_result {
Ok(video) => { Ok(video) => {
if let Some(tokio_video_file) = video.file.as_any().downcast_ref::<TokioVideoFile>() { if let Some(tokio_video_file) = video.file.as_any().downcast_ref::<TokioVideoFile>() {
@@ -39,6 +38,7 @@ pub async fn get_video_stream(
Ok(file) => HttpResponse::Ok() Ok(file) => HttpResponse::Ok()
.content_type("application/octet-stream") .content_type("application/octet-stream")
.streaming(async_stream::stream! { .streaming(async_stream::stream! {
let file = tokio::fs::File::from_std(file);
let mut stream = FramedRead::new(file, BytesCodec::new()); let mut stream = FramedRead::new(file, BytesCodec::new());
while let Some(chunk) = stream.next().await { while let Some(chunk) = stream.next().await {
yield chunk.map(|bytes| bytes.freeze()); yield chunk.map(|bytes| bytes.freeze());
+12
View File
@@ -0,0 +1,12 @@
:host {
display: flex;
flex-direction: column;
gap: 1em;
}
.items-container {
display: flex;
flex-direction: column;
gap: .7em;
padding: 0 .5em;
}
+8 -3
View File
@@ -4,15 +4,20 @@
</div> </div>
<div class="items-container"> <div class="items-container">
@for (item of libraryItems.value(); track item.id) { @for (item of libraryItems.value(); track item.id) {
@if (item.type === 'VIDEO') {
<button type="button" (click)="activeVideo.set(item)">
[{{item.type[0]}}] ({{item.id.substring(0, 4)}}…) {{item.name}}
</button>
} @else {
<div class="item"> <div class="item">
[{{item.type[0]}}] ({{item.id.substring(0, 4)}}…) {{item.name}} [{{item.type[0]}}] ({{item.id.substring(0, 4)}}…) {{item.name}}
</div> </div>
} }
}
</div> </div>
<div> <div>
@if (firstVideo(); as firstVideo) { @if (activeVideo(); as firstVideo) {
<video controls> <video width="320" height="240" src="/api/videos/{{firstVideo.id}}/stream" controls>
<source src="/api/videos/{{firstVideo.id}}/stream" type="video/mp4">
Your browser does not support the html video player. Your browser does not support the html video player.
</video> </video>
} }
+1 -4
View File
@@ -28,10 +28,7 @@ export class App implements OnInit {
loader: ({}) => firstValueFrom(this.#httpClient.get<LibraryItem[]>('/api/library')) loader: ({}) => firstValueFrom(this.#httpClient.get<LibraryItem[]>('/api/library'))
}); });
firstVideo = computed(() => { activeVideo = signal<LibraryItem | null>(null);
const libraryItems = this.libraryItems.value() ?? [];
return libraryItems.length ? libraryItems[0] : null
});
ngOnInit(): void { ngOnInit(): void {
this.loadLibrary(); this.loadLibrary();