diff --git a/ngx_http_vod_module.c b/ngx_http_vod_module.c index 81f4da9e..340cf946 100644 --- a/ngx_http_vod_module.c +++ b/ngx_http_vod_module.c @@ -5219,6 +5219,7 @@ ngx_http_vod_map_media_set_apply(ngx_http_vod_ctx_t *ctx, ngx_str_t* mapping, in sequence->language = mapped_media_set.sequences->language; sequence->label = mapped_media_set.sequences->label; sequence->with_accessibility = mapped_media_set.sequences->with_accessibility; + sequence->forced = mapped_media_set.sequences->forced; sequence->id = mapped_media_set.sequences->id; ngx_memcpy(sequence->bitrate, mapped_media_set.sequences->bitrate, sizeof(sequence->bitrate)); ngx_memcpy(sequence->avg_bitrate, mapped_media_set.sequences->avg_bitrate, sizeof(sequence->avg_bitrate)); diff --git a/ngx_http_vod_request_parse.c b/ngx_http_vod_request_parse.c index c21f5898..9bba3921 100644 --- a/ngx_http_vod_request_parse.c +++ b/ngx_http_vod_request_parse.c @@ -1078,6 +1078,7 @@ ngx_http_vod_parse_uri_path( cur_sequence->language = 0; cur_sequence->label.len = 0; cur_sequence->with_accessibility = FALSE; + cur_sequence->forced = FALSE; cur_sequence->first_key_frame_offset = 0; cur_sequence->key_frame_durations = NULL; cur_sequence->drm_info = NULL; diff --git a/vod/hls/m3u8_builder.c b/vod/hls/m3u8_builder.c index f484fa12..1aea8baf 100644 --- a/vod/hls/m3u8_builder.c +++ b/vod/hls/m3u8_builder.c @@ -16,6 +16,8 @@ #define M3U8_EXT_MEDIA_DEFAULT "AUTOSELECT=YES,DEFAULT=YES," #define M3U8_EXT_MEDIA_AUTOSELECT "AUTOSELECT=YES,DEFAULT=NO," #define M3U8_EXT_MEDIA_NON_DEFAULT "AUTOSELECT=NO,DEFAULT=NO," +#define M3U8_EXT_MEDIA_FORCED "FORCED=YES," +#define M3U8_EXT_MEDIA_NON_FORCED "FORCED=NO," #define M3U8_EXT_MEDIA_AD "CHARACTERISTICS=\"public.accessibility.describes-video\"," #define M3U8_EXT_MEDIA_SDH "CHARACTERISTICS=\"public.accessibility.describes-music-and-sound\"," #define M3U8_EXT_MEDIA_URI "URI=\"" @@ -861,6 +863,18 @@ m3u8_builder_ext_x_media_tags_get_size( } } + if (media_type == MEDIA_TYPE_SUBTITLE) + { + if (cur_track->media_info.forced) + { + result += sizeof(M3U8_EXT_MEDIA_FORCED) - 1; + } + else + { + result += sizeof(M3U8_EXT_MEDIA_NON_FORCED) - 1; + } + } + if (base_url->len != 0) { result += vod_max(cur_track->file_info.uri.len, media_set->uri.len); @@ -972,6 +986,18 @@ m3u8_builder_ext_x_media_tags_write( p = vod_copy(p, M3U8_EXT_MEDIA_NON_DEFAULT, sizeof(M3U8_EXT_MEDIA_NON_DEFAULT) - 1); } + if (media_type == MEDIA_TYPE_SUBTITLE) + { + if (tracks[media_type]->media_info.forced) + { + p = vod_copy(p, M3U8_EXT_MEDIA_FORCED, sizeof(M3U8_EXT_MEDIA_FORCED) - 1); + } + else + { + p = vod_copy(p, M3U8_EXT_MEDIA_NON_FORCED, sizeof(M3U8_EXT_MEDIA_NON_FORCED) - 1); + } + } + if (media_type == MEDIA_TYPE_AUDIO) { p = vod_sprintf(p, M3U8_EXT_MEDIA_CHANNELS, diff --git a/vod/input/silence_generator.c b/vod/input/silence_generator.c index d320e276..e6180e21 100644 --- a/vod/input/silence_generator.c +++ b/vod/input/silence_generator.c @@ -105,6 +105,7 @@ silence_generator_generate( track->media_info.label = sequence->label; track->media_info.language = sequence->language; track->media_info.with_accessibility = sequence->with_accessibility; + track->media_info.forced = sequence->forced; rc = media_format_finalize_track( request_context, diff --git a/vod/media_format.h b/vod/media_format.h index 62019a91..66dc368b 100644 --- a/vod/media_format.h +++ b/vod/media_format.h @@ -218,6 +218,7 @@ typedef struct media_info_s { language_id_t language; vod_str_t label; bool_t with_accessibility; + bool_t forced; union { video_media_info_t video; audio_media_info_t audio; diff --git a/vod/media_set.h b/vod/media_set.h index f554d07d..50975cb1 100644 --- a/vod/media_set.h +++ b/vod/media_set.h @@ -61,6 +61,7 @@ struct media_sequence_s { vod_str_t label; language_id_t language; bool_t with_accessibility; // Closed Captions for subtitle, Audio Description for audio + bool_t forced; // Forced for subtitle only uint32_t bitrate[MEDIA_TYPE_COUNT]; uint32_t avg_bitrate[MEDIA_TYPE_COUNT]; int64_t first_key_frame_offset; diff --git a/vod/media_set_parser.c b/vod/media_set_parser.c index 30375363..5d5be817 100644 --- a/vod/media_set_parser.c +++ b/vod/media_set_parser.c @@ -124,6 +124,7 @@ static json_object_value_def_t media_sequence_params[] = { { vod_string("language"), VOD_JSON_STRING, offsetof(media_sequence_t, language), media_set_parse_language }, { vod_string("label"), VOD_JSON_STRING, offsetof(media_sequence_t, label), media_set_parse_null_term_string }, { vod_string("withAccessibility"),VOD_JSON_BOOL, offsetof(media_sequence_t, with_accessibility), media_set_parse_bool }, + { vod_string("forced"), VOD_JSON_BOOL, offsetof(media_sequence_t, forced), media_set_parse_bool }, { vod_string("bitrate"), VOD_JSON_OBJECT, offsetof(media_sequence_t, bitrate), media_set_parse_bitrate }, { vod_string("avg_bitrate"), VOD_JSON_OBJECT, offsetof(media_sequence_t, avg_bitrate), media_set_parse_bitrate }, { vod_null_string, 0, 0, NULL } @@ -841,6 +842,7 @@ media_set_parse_sequences( cur_output->language = 0; cur_output->label.len = 0; cur_output->with_accessibility = FALSE; + cur_output->forced = FALSE; cur_output->first_key_frame_offset = 0; cur_output->key_frame_durations = NULL; cur_output->drm_info = NULL; diff --git a/vod/mp4/mp4_parser.c b/vod/mp4/mp4_parser.c index c994cd0a..99f48001 100644 --- a/vod/mp4/mp4_parser.c +++ b/vod/mp4/mp4_parser.c @@ -2791,6 +2791,7 @@ mp4_parser_process_moov_atom_callback(void* ctx, atom_info_t* atom_info) // inherit the sequence language and label sequence = context->parse_params.source->sequence; metadata_parse_context.media_info.with_accessibility = sequence->with_accessibility; + metadata_parse_context.media_info.forced = sequence->forced; if (sequence->label.len != 0) { metadata_parse_context.media_info.label = sequence->label; diff --git a/vod/subtitle/subtitle_format.c b/vod/subtitle/subtitle_format.c index f9a786ef..efa0503c 100644 --- a/vod/subtitle/subtitle_format.c +++ b/vod/subtitle/subtitle_format.c @@ -71,6 +71,7 @@ subtitle_parse( language_id_t lang_id; vod_str_t label; bool_t with_accessibility; + bool_t forced; uint64_t duration; metadata = vod_alloc(request_context->pool, sizeof(*metadata)); @@ -92,6 +93,7 @@ subtitle_parse( // inherit the sequence language and label sequence = parse_params->source->sequence; with_accessibility = sequence->with_accessibility; + forced = sequence->forced; if (sequence->label.len != 0) { label = sequence->label; @@ -145,6 +147,7 @@ subtitle_parse( track->media_info.label = label; track->media_info.language = lang_id; track->media_info.with_accessibility = with_accessibility; + track->media_info.forced = forced; track->media_info.bitrate = (source->len * 1000 * 8) / full_duration; metadata->source = *source;