From 482d9faaabeb4612c5789010a945676cc707e71c Mon Sep 17 00:00:00 2001 From: Kostya Bats Date: Sat, 23 Mar 2024 16:52:38 +0300 Subject: [PATCH] refactor hls supporting --- schemas/advanced.schema.json | 22 ++++++------- .../icpclive/export/clics/ClicsExporter.kt | 3 +- src/cds/core/api/core.api | 32 +++++++++++++++++++ .../org/icpclive/cds/api/ContestInfo.kt | 1 - .../kotlin/org/icpclive/cds/api/MediaType.kt | 6 +++- .../icpclive/cds/plugins/clics/ClicsModel.kt | 3 ++ src/frontend/generated/api.ts | 4 +-- .../organisms/holder/ContestantViewHolder.tsx | 7 ++-- 8 files changed, 58 insertions(+), 20 deletions(-) diff --git a/schemas/advanced.schema.json b/schemas/advanced.schema.json index 080a8be02..f21137b8f 100644 --- a/schemas/advanced.schema.json +++ b/schemas/advanced.schema.json @@ -1,16 +1,19 @@ { "$ref": "#/$defs/ICPC live advanced settings", "$defs": { - "M2tsVideo": { + "HLSVideo": { "type": "object", "properties": { "type": { - "const": "M2tsVideo", - "default": "M2tsVideo" + "const": "HLSVideo", + "default": "HLSVideo" }, "url": { "type": "string" }, + "jwtToken": { + "type": "string" + }, "isMedia": { "type": "boolean" } @@ -20,21 +23,18 @@ "type", "url" ], - "title": "M2tsVideo" + "title": "HLSVideo" }, - "HLSVideo": { + "M2tsVideo": { "type": "object", "properties": { "type": { - "const": "HLSVideo", - "default": "HLSVideo" + "const": "M2tsVideo", + "default": "M2tsVideo" }, "url": { "type": "string" }, - "jwtToken": { - "type": "string" - }, "isMedia": { "type": "boolean" } @@ -44,7 +44,7 @@ "type", "url" ], - "title": "HLSVideo" + "title": "M2tsVideo" }, "Object": { "type": "object", diff --git a/src/cds-converter/src/main/kotlin/org/icpclive/export/clics/ClicsExporter.kt b/src/cds-converter/src/main/kotlin/org/icpclive/export/clics/ClicsExporter.kt index f818d64e7..4c727c6bd 100644 --- a/src/cds-converter/src/main/kotlin/org/icpclive/export/clics/ClicsExporter.kt +++ b/src/cds-converter/src/main/kotlin/org/icpclive/export/clics/ClicsExporter.kt @@ -51,6 +51,7 @@ private fun MediaType.toClicsMedia() = when (this) { is MediaType.TaskStatus -> null is MediaType.Video -> Media("video", url) is MediaType.M2tsVideo -> Media("video/m2ts", url) + is MediaType.HLSVideo -> Media("application/vnd.apple.mpegurl", url) is MediaType.WebRTCGrabberConnection -> null is MediaType.WebRTCProxyConnection -> null } @@ -487,4 +488,4 @@ object ClicsExporter { )) } } -} \ No newline at end of file +} diff --git a/src/cds/core/api/core.api b/src/cds/core/api/core.api index 1214ae769..7dc73dd52 100644 --- a/src/cds/core/api/core.api +++ b/src/cds/core/api/core.api @@ -781,6 +781,38 @@ public final class org/icpclive/cds/api/MediaType$Companion { public final fun serializer ()Lkotlinx/serialization/KSerializer; } +public final class org/icpclive/cds/api/MediaType$HLSVideo : org/icpclive/cds/api/MediaType { + public static final field Companion Lorg/icpclive/cds/api/MediaType$HLSVideo$Companion; + public fun (Ljava/lang/String;Ljava/lang/String;Z)V + public synthetic fun (Ljava/lang/String;Ljava/lang/String;ZILkotlin/jvm/internal/DefaultConstructorMarker;)V + public final fun component1 ()Ljava/lang/String; + public final fun component2 ()Ljava/lang/String; + public final fun component3 ()Z + public final fun copy (Ljava/lang/String;Ljava/lang/String;Z)Lorg/icpclive/cds/api/MediaType$HLSVideo; + public static synthetic fun copy$default (Lorg/icpclive/cds/api/MediaType$HLSVideo;Ljava/lang/String;Ljava/lang/String;ZILjava/lang/Object;)Lorg/icpclive/cds/api/MediaType$HLSVideo; + public fun equals (Ljava/lang/Object;)Z + public final fun getJwtToken ()Ljava/lang/String; + public final fun getUrl ()Ljava/lang/String; + public fun hashCode ()I + public fun isMedia ()Z + public fun toString ()Ljava/lang/String; +} + +public synthetic class org/icpclive/cds/api/MediaType$HLSVideo$$serializer : kotlinx/serialization/internal/GeneratedSerializer { + public static final field INSTANCE Lorg/icpclive/cds/api/MediaType$HLSVideo$$serializer; + public final fun childSerializers ()[Lkotlinx/serialization/KSerializer; + public synthetic fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Ljava/lang/Object; + public final fun deserialize (Lkotlinx/serialization/encoding/Decoder;)Lorg/icpclive/cds/api/MediaType$HLSVideo; + public final fun getDescriptor ()Lkotlinx/serialization/descriptors/SerialDescriptor; + public synthetic fun serialize (Lkotlinx/serialization/encoding/Encoder;Ljava/lang/Object;)V + public final fun serialize (Lkotlinx/serialization/encoding/Encoder;Lorg/icpclive/cds/api/MediaType$HLSVideo;)V + public fun typeParametersSerializers ()[Lkotlinx/serialization/KSerializer; +} + +public final class org/icpclive/cds/api/MediaType$HLSVideo$Companion { + public final fun serializer ()Lkotlinx/serialization/KSerializer; +} + public final class org/icpclive/cds/api/MediaType$M2tsVideo : org/icpclive/cds/api/MediaType { public static final field Companion Lorg/icpclive/cds/api/MediaType$M2tsVideo$Companion; public fun (Ljava/lang/String;Z)V diff --git a/src/cds/core/src/main/kotlin/org/icpclive/cds/api/ContestInfo.kt b/src/cds/core/src/main/kotlin/org/icpclive/cds/api/ContestInfo.kt index cd3e1bcb1..7756c4107 100644 --- a/src/cds/core/src/main/kotlin/org/icpclive/cds/api/ContestInfo.kt +++ b/src/cds/core/src/main/kotlin/org/icpclive/cds/api/ContestInfo.kt @@ -116,4 +116,3 @@ public data class ContestInfo( val problems: Map by lazy { problemList.associateBy { it.id } } val scoreboardProblems: List by lazy { problemList.sortedBy { it.ordinal }.filterNot { it.isHidden } } } - diff --git a/src/cds/core/src/main/kotlin/org/icpclive/cds/api/MediaType.kt b/src/cds/core/src/main/kotlin/org/icpclive/cds/api/MediaType.kt index 4a85d1ed7..d5e84e824 100644 --- a/src/cds/core/src/main/kotlin/org/icpclive/cds/api/MediaType.kt +++ b/src/cds/core/src/main/kotlin/org/icpclive/cds/api/MediaType.kt @@ -23,6 +23,10 @@ public sealed class MediaType { @SerialName("M2tsVideo") public data class M2tsVideo(val url: String, override val isMedia: Boolean = true) : MediaType() + @Serializable + @SerialName("HLSVideo") + public data class HLSVideo(val url: String, val jwtToken: String? = null, override val isMedia: Boolean = true) : MediaType() + /** * WebRTC proxy connection * @see https://github.com/kbats183/webrtc-proxy @@ -65,4 +69,4 @@ public sealed class MediaType { is WebRTCGrabberConnection -> copy(isMedia = false) else -> this } -} \ No newline at end of file +} diff --git a/src/cds/plugins/clics/src/main/kotlin/org/icpclive/cds/plugins/clics/ClicsModel.kt b/src/cds/plugins/clics/src/main/kotlin/org/icpclive/cds/plugins/clics/ClicsModel.kt index b206276a8..1afa6441d 100644 --- a/src/cds/plugins/clics/src/main/kotlin/org/icpclive/cds/plugins/clics/ClicsModel.kt +++ b/src/cds/plugins/clics/src/main/kotlin/org/icpclive/cds/plugins/clics/ClicsModel.kt @@ -44,6 +44,9 @@ internal class ClicsModel(private val addTeamNames: Boolean) { if (mime.startsWith("video/m2ts")) { return MediaType.M2tsVideo(href) } + if (mime.startsWith("application/vnd.apple.mpegurl")) { + return MediaType.HLSVideo(href) + } if (mime.startsWith("video")) { return MediaType.Video(href) } diff --git a/src/frontend/generated/api.ts b/src/frontend/generated/api.ts index 986888d3c..1bd8fd425 100644 --- a/src/frontend/generated/api.ts +++ b/src/frontend/generated/api.ts @@ -131,13 +131,13 @@ export namespace MediaType { jwtToken?: string | null; isMedia?: boolean; } - + export interface M2tsVideo { type: MediaType.Type.M2tsVideo; url: string; isMedia?: boolean; } - + export interface Object { type: MediaType.Type.Object; url: string; diff --git a/src/frontend/overlay/src/components/organisms/holder/ContestantViewHolder.tsx b/src/frontend/overlay/src/components/organisms/holder/ContestantViewHolder.tsx index 1d1fac898..1e1521521 100644 --- a/src/frontend/overlay/src/components/organisms/holder/ContestantViewHolder.tsx +++ b/src/frontend/overlay/src/components/organisms/holder/ContestantViewHolder.tsx @@ -52,7 +52,7 @@ export const TeamM2tsVideoWrapper = ({ url, setIsLoaded }) => { if (videoRef.current) { videoRef.current.srcObject = null; } - } + }; }, [url]); return (; + if (Hls.isSupported()) return ; // Fallback to using a regular video player if HLS is supported by default in the user's browser - return