Skip to content

Commit 2b585f6

Browse files
authored
Merge pull request #11 from Eyevinn/segmented-audio-encode
Segmented audio encode
2 parents 4d13976 + ecaecce commit 2b585f6

File tree

23 files changed

+1612
-207
lines changed

23 files changed

+1612
-207
lines changed

checks.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ jacocoTestCoverageVerification {
1919
'*FfmpegExecutor.runFfmpeg$lambda$?(java.lang.Process)',
2020
'*FfmpegExecutorKt.getProgressRegex()',
2121
'*FilterSettings.*',
22+
'se.svt.oss.encore.service.EncoreService.handleProgress.1.1.emit(int, kotlin.coroutines.Continuation)',
2223
]
2324
limit {
2425
counter = 'LINE'

encore-common/src/main/kotlin/se/svt/oss/encore/config/EncodingProperties.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,11 @@ package se.svt.oss.encore.config
66

77
import org.springframework.boot.context.properties.NestedConfigurationProperty
88
import org.springframework.core.io.Resource
9+
import se.svt.oss.encore.model.AudioEncodingMode
910
import se.svt.oss.encore.model.profile.ChannelLayout
1011

1112
data class SegmentedEncodingProperties(
12-
val enabledForAudio: Boolean = true,
13+
val audioEncodingMode: AudioEncodingMode = AudioEncodingMode.ENCODE_WITH_VIDEO,
1314
)
1415

1516
data class EncodingProperties(
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// SPDX-FileCopyrightText: 2025 Eyevinn Technology AB
2+
//
3+
// SPDX-License-Identifier: EUPL-1.2
4+
5+
package se.svt.oss.encore.model
6+
7+
/**
8+
* Defines how audio should be encoded when using segmented encoding.
9+
*/
10+
enum class AudioEncodingMode {
11+
/**
12+
* Encode audio and video together in the same segments.
13+
* Creates N tasks of type AUDIOVIDEOSEGMENT.
14+
*/
15+
ENCODE_WITH_VIDEO,
16+
17+
/**
18+
* Encode audio separately from video as a single full-length file (not segmented).
19+
* Creates 1 AUDIOFULL task + N VIDEOSEGMENT tasks.
20+
*/
21+
ENCODE_SEPARATELY_FULL,
22+
23+
/**
24+
* Encode audio separately from video, with both audio and video segmented.
25+
* Creates N AUDIOSEGMENT tasks + N VIDEOSEGMENT tasks (2N total tasks).
26+
*/
27+
ENCODE_SEPARATELY_SEGMENTED,
28+
}

encore-common/src/main/kotlin/se/svt/oss/encore/model/EncoreJob.kt

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,24 +30,44 @@ data class SegmentedEncodingInfo(
3030
)
3131
val segmentLength: Double,
3232
@field:Schema(
33-
description = "Number of segments",
33+
description = "Number of video segments",
3434
nullable = false,
3535
readOnly = true,
3636
)
3737
val numSegments: Int,
3838
@field:Schema(
39-
description = "Number of encoding tasks used for this job. This is either the number of segments, or the number of segments + 1 if separate audio encode is used.",
39+
description = "Number of encoding tasks used for this job. This will be equal to numSegments plus numAudioSegments",
4040
nullable = false,
4141
readOnly = true,
4242
)
4343
val numTasks: Int,
4444
@field:Schema(
45-
description = "Indicates if audio is encoded in segments. Otherwise a separate task will be used to encode the full audio.",
46-
example = "true",
45+
description = "The audio encoding mode used for this job.",
46+
example = "ENCODE_WITH_VIDEO",
4747
nullable = false,
4848
readOnly = true,
4949
)
50-
val segmentedAudioEncode: Boolean,
50+
val audioEncodingMode: AudioEncodingMode,
51+
@field:Schema(
52+
description = "Audio segment padding in seconds (added at start/end of segments to avoid artifacts). Only relevant in ENCODE_SEPARATELY_SEGMENTED mode.",
53+
example = "0.04267",
54+
nullable = false,
55+
readOnly = true,
56+
)
57+
val audioSegmentPadding: Double = 0.0,
58+
@field:Schema(
59+
description = "Length of each audio segment in seconds. Only relevant in ENCODE_SEPARATELY_SEGMENTED mode.",
60+
example = "256.0",
61+
nullable = false,
62+
readOnly = true,
63+
)
64+
val audioSegmentLength: Double = 0.0,
65+
@field:Schema(
66+
description = "Number of audio segments",
67+
nullable = false,
68+
readOnly = true,
69+
)
70+
val numAudioSegments: Int,
5171
)
5272

5373
@Validated
@@ -137,12 +157,20 @@ data class EncoreJob(
137157
val segmentLength: Double? = null,
138158

139159
@field:Schema(
140-
description = "If true, and segmented encoding i used, audio will be encoded in segments. Otherwise a separate task will be used to encode the full audio.",
141-
example = "true",
142-
defaultValue = "true",
160+
description = "Defines how audio should be encoded when using segmented encoding. ENCODE_WITH_VIDEO: audio and video together in segments; ENCODE_SEPARATELY_FULL: audio separately as full file; ENCODE_SEPARATELY_SEGMENTED: audio separately in segments.",
161+
example = "ENCODE_WITH_VIDEO",
162+
defaultValue = "ENCODE_WITH_VIDEO",
163+
nullable = true,
164+
)
165+
val audioEncodingMode: AudioEncodingMode? = null,
166+
167+
@field:Schema(
168+
description = "Length of audio segments in seconds when using ENCODE_SEPARATELY_SEGMENTED mode. If not specified, a value close to 256s will be calculated that is a multiple of the audio frame size.",
169+
example = "256.0",
143170
nullable = true,
144171
)
145-
val segmentedEncodingEnabledForAudio: Boolean? = null,
172+
@field:Positive
173+
val audioSegmentLength: Double? = null,
146174

147175
@field:Schema(
148176
description = "Properties for segmented encoding, or null if not used",

encore-common/src/main/kotlin/se/svt/oss/encore/model/profile/AudioEncode.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import se.svt.oss.encore.model.output.AudioStreamEncode
1717
import se.svt.oss.encore.model.output.Output
1818

1919
data class AudioEncode(
20-
val codec: String = "libfdk_aac",
20+
override val codec: String = "libfdk_aac",
2121
val bitrate: String? = null,
2222
val samplerate: Int = 48000,
2323
val channelLayout: ChannelLayout = ChannelLayout.CH_LAYOUT_STEREO,

encore-common/src/main/kotlin/se/svt/oss/encore/model/profile/AudioEncoder.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ private val log = KotlinLogging.logger { }
1212
abstract class AudioEncoder : OutputProducer {
1313

1414
abstract val optional: Boolean
15-
abstract val enabled: Boolean
15+
abstract val codec: String
16+
abstract override val enabled: Boolean
1617

1718
fun logOrThrow(message: String): Output? {
1819
if (optional || !enabled) {

encore-common/src/main/kotlin/se/svt/oss/encore/model/profile/OutputProducer.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,5 +21,6 @@ import se.svt.oss.encore.model.output.Output
2121
JsonSubTypes.Type(value = ThumbnailMapEncode::class, name = "ThumbnailMapEncode"),
2222
)
2323
interface OutputProducer {
24+
val enabled: Boolean
2425
fun getOutput(job: EncoreJob, encodingProperties: EncodingProperties, filterSettings: FilterSettings): Output?
2526
}

encore-common/src/main/kotlin/se/svt/oss/encore/model/profile/SimpleAudioEncode.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import se.svt.oss.encore.model.output.AudioStreamEncode
1313
import se.svt.oss.encore.model.output.Output
1414

1515
data class SimpleAudioEncode(
16-
val codec: String = "libfdk_aac",
16+
override val codec: String = "libfdk_aac",
1717
val bitrate: String? = null,
1818
val samplerate: Int? = null,
1919
val suffix: String = "_$codec",

encore-common/src/main/kotlin/se/svt/oss/encore/model/profile/ThumbnailEncode.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ data class ThumbnailEncode(
2525
val suffixZeroPad: Int = 2,
2626
val inputLabel: String = DEFAULT_VIDEO_LABEL,
2727
val optional: Boolean = false,
28-
val enabled: Boolean = true,
28+
override val enabled: Boolean = true,
2929
val intervalSeconds: Double? = null,
3030
val decodeOutput: Int? = null,
3131
) : OutputProducer {

encore-common/src/main/kotlin/se/svt/oss/encore/model/profile/ThumbnailMapEncode.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ data class ThumbnailMapEncode(
2626
val rows: Int = 20,
2727
val quality: Int = 5,
2828
val optional: Boolean = true,
29-
val enabled: Boolean = true,
29+
override val enabled: Boolean = true,
3030
val suffix: String = "_${cols}x${rows}_${tileWidth}x${tileHeight}_thumbnail_map",
3131
val format: String = "jpg",
3232
val inputLabel: String = DEFAULT_VIDEO_LABEL,

0 commit comments

Comments
 (0)