mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2025-01-03 21:42:09 +00:00
avformat/hlsenc: merge mpegts and fmp4 workflow to one workflow
write mpegts or fmp4 context into buffer, and flush the buffer into output file when split fragment. merge two format split workflow into one workflow Signed-off-by: Steven Liu <lq@chinaffmpeg.org>
This commit is contained in:
parent
df6e341b04
commit
cff309097a
@ -815,7 +815,7 @@ static int hls_mux_init(AVFormatContext *s, VariantStream *vs)
|
||||
vs->start_pos = 0;
|
||||
vs->new_start = 1;
|
||||
|
||||
if (hls->segment_type == SEGMENT_TYPE_FMP4) {
|
||||
if (hls->segment_type == SEGMENT_TYPE_FMP4 && hls->max_seg_size > 0) {
|
||||
if (hls->http_persistent > 0) {
|
||||
//TODO: Support fragment fmp4 for http persistent in HLS muxer.
|
||||
av_log(s, AV_LOG_WARNING, "http persistent mode is currently unsupported for fragment mp4 in the HLS muxer.\n");
|
||||
@ -824,34 +824,38 @@ static int hls_mux_init(AVFormatContext *s, VariantStream *vs)
|
||||
av_log(s, AV_LOG_WARNING, "Multi-file byterange mode is currently unsupported in the HLS muxer.\n");
|
||||
return AVERROR_PATCHWELCOME;
|
||||
}
|
||||
}
|
||||
|
||||
vs->packets_written = 0;
|
||||
vs->init_range_length = 0;
|
||||
set_http_options(s, &options, hls);
|
||||
if ((ret = avio_open_dyn_buf(&oc->pb)) < 0)
|
||||
return ret;
|
||||
vs->packets_written = 0;
|
||||
vs->init_range_length = 0;
|
||||
set_http_options(s, &options, hls);
|
||||
if ((ret = avio_open_dyn_buf(&oc->pb)) < 0)
|
||||
return ret;
|
||||
|
||||
if (hls->segment_type == SEGMENT_TYPE_FMP4) {
|
||||
if (byterange_mode) {
|
||||
ret = hlsenc_io_open(s, &vs->out, vs->basename, &options);
|
||||
} else {
|
||||
ret = hlsenc_io_open(s, &vs->out, vs->base_output_dirname, &options);
|
||||
}
|
||||
av_dict_free(&options);
|
||||
}
|
||||
av_dict_free(&options);
|
||||
if (ret < 0) {
|
||||
av_log(s, AV_LOG_ERROR, "Failed to open segment '%s'\n", vs->fmp4_init_filename);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (hls->format_options_str) {
|
||||
ret = av_dict_parse_string(&hls->format_options, hls->format_options_str, "=", ":", 0);
|
||||
if (ret < 0) {
|
||||
av_log(s, AV_LOG_ERROR, "Failed to open segment '%s'\n", vs->fmp4_init_filename);
|
||||
av_log(s, AV_LOG_ERROR, "Could not parse format options list '%s'\n",
|
||||
hls->format_options_str);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (hls->format_options_str) {
|
||||
ret = av_dict_parse_string(&hls->format_options, hls->format_options_str, "=", ":", 0);
|
||||
if (ret < 0) {
|
||||
av_log(s, AV_LOG_ERROR, "Could not parse format options list '%s'\n",
|
||||
hls->format_options_str);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
av_dict_copy(&options, hls->format_options, 0);
|
||||
av_dict_copy(&options, hls->format_options, 0);
|
||||
if (hls->segment_type == SEGMENT_TYPE_FMP4) {
|
||||
av_dict_set(&options, "fflags", "-autobsf", 0);
|
||||
av_dict_set(&options, "movflags", "+frag_custom+dash+delay_moov", AV_DICT_APPEND);
|
||||
ret = avformat_init_output(oc, &options);
|
||||
@ -862,9 +866,9 @@ static int hls_mux_init(AVFormatContext *s, VariantStream *vs)
|
||||
av_dict_free(&options);
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
avio_flush(oc->pb);
|
||||
av_dict_free(&options);
|
||||
}
|
||||
avio_flush(oc->pb);
|
||||
av_dict_free(&options);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1435,7 +1439,6 @@ static int hls_window(AVFormatContext *s, int last, VariantStream *vs)
|
||||
{
|
||||
HLSContext *hls = s->priv_data;
|
||||
HLSSegment *en;
|
||||
AVFormatContext *oc = vs->avf;
|
||||
int target_duration = 0;
|
||||
int ret = 0;
|
||||
char temp_filename[MAX_URL_SIZE];
|
||||
@ -1471,7 +1474,7 @@ static int hls_window(AVFormatContext *s, int last, VariantStream *vs)
|
||||
|
||||
set_http_options(s, &options, hls);
|
||||
snprintf(temp_filename, sizeof(temp_filename), use_temp_file ? "%s.tmp" : "%s", vs->m3u8_name);
|
||||
if ((ret = hlsenc_io_open(s, (byterange_mode || hls->segment_type == SEGMENT_TYPE_FMP4) ? &hls->m3u8_out : &oc->pb, temp_filename, &options)) < 0) {
|
||||
if ((ret = hlsenc_io_open(s, (byterange_mode || hls->segment_type == SEGMENT_TYPE_FMP4) ? &hls->m3u8_out : &vs->out, temp_filename, &options)) < 0) {
|
||||
if (hls->ignore_io_errors)
|
||||
ret = 0;
|
||||
goto fail;
|
||||
@ -1483,33 +1486,33 @@ static int hls_window(AVFormatContext *s, int last, VariantStream *vs)
|
||||
}
|
||||
|
||||
vs->discontinuity_set = 0;
|
||||
ff_hls_write_playlist_header((byterange_mode || hls->segment_type == SEGMENT_TYPE_FMP4) ? hls->m3u8_out : oc->pb, hls->version, hls->allowcache,
|
||||
ff_hls_write_playlist_header((byterange_mode || hls->segment_type == SEGMENT_TYPE_FMP4) ? hls->m3u8_out : vs->out, hls->version, hls->allowcache,
|
||||
target_duration, sequence, hls->pl_type, hls->flags & HLS_I_FRAMES_ONLY);
|
||||
|
||||
if((hls->flags & HLS_DISCONT_START) && sequence==hls->start_sequence && vs->discontinuity_set==0 ){
|
||||
avio_printf((byterange_mode || hls->segment_type == SEGMENT_TYPE_FMP4) ? hls->m3u8_out : oc->pb, "#EXT-X-DISCONTINUITY\n");
|
||||
avio_printf((byterange_mode || hls->segment_type == SEGMENT_TYPE_FMP4) ? hls->m3u8_out : vs->out, "#EXT-X-DISCONTINUITY\n");
|
||||
vs->discontinuity_set = 1;
|
||||
}
|
||||
if (vs->has_video && (hls->flags & HLS_INDEPENDENT_SEGMENTS)) {
|
||||
avio_printf((byterange_mode || hls->segment_type == SEGMENT_TYPE_FMP4) ? hls->m3u8_out : oc->pb, "#EXT-X-INDEPENDENT-SEGMENTS\n");
|
||||
avio_printf((byterange_mode || hls->segment_type == SEGMENT_TYPE_FMP4) ? hls->m3u8_out : vs->out, "#EXT-X-INDEPENDENT-SEGMENTS\n");
|
||||
}
|
||||
for (en = vs->segments; en; en = en->next) {
|
||||
if ((hls->encrypt || hls->key_info_file) && (!key_uri || strcmp(en->key_uri, key_uri) ||
|
||||
av_strcasecmp(en->iv_string, iv_string))) {
|
||||
avio_printf((byterange_mode || hls->segment_type == SEGMENT_TYPE_FMP4) ? hls->m3u8_out : oc->pb, "#EXT-X-KEY:METHOD=AES-128,URI=\"%s\"", en->key_uri);
|
||||
avio_printf((byterange_mode || hls->segment_type == SEGMENT_TYPE_FMP4) ? hls->m3u8_out : vs->out, "#EXT-X-KEY:METHOD=AES-128,URI=\"%s\"", en->key_uri);
|
||||
if (*en->iv_string)
|
||||
avio_printf((byterange_mode || hls->segment_type == SEGMENT_TYPE_FMP4) ? hls->m3u8_out : oc->pb, ",IV=0x%s", en->iv_string);
|
||||
avio_printf((byterange_mode || hls->segment_type == SEGMENT_TYPE_FMP4) ? hls->m3u8_out : oc->pb, "\n");
|
||||
avio_printf((byterange_mode || hls->segment_type == SEGMENT_TYPE_FMP4) ? hls->m3u8_out : vs->out, ",IV=0x%s", en->iv_string);
|
||||
avio_printf((byterange_mode || hls->segment_type == SEGMENT_TYPE_FMP4) ? hls->m3u8_out : vs->out, "\n");
|
||||
key_uri = en->key_uri;
|
||||
iv_string = en->iv_string;
|
||||
}
|
||||
|
||||
if ((hls->segment_type == SEGMENT_TYPE_FMP4) && (en == vs->segments)) {
|
||||
ff_hls_write_init_file((byterange_mode || hls->segment_type == SEGMENT_TYPE_FMP4) ? hls->m3u8_out : oc->pb, (hls->flags & HLS_SINGLE_FILE) ? en->filename : vs->fmp4_init_filename,
|
||||
ff_hls_write_init_file((byterange_mode || hls->segment_type == SEGMENT_TYPE_FMP4) ? hls->m3u8_out : vs->out, (hls->flags & HLS_SINGLE_FILE) ? en->filename : vs->fmp4_init_filename,
|
||||
hls->flags & HLS_SINGLE_FILE, vs->init_range_length, 0);
|
||||
}
|
||||
|
||||
ret = ff_hls_write_file_entry((byterange_mode || hls->segment_type == SEGMENT_TYPE_FMP4) ? hls->m3u8_out : oc->pb, en->discont, byterange_mode,
|
||||
ret = ff_hls_write_file_entry((byterange_mode || hls->segment_type == SEGMENT_TYPE_FMP4) ? hls->m3u8_out : vs->out, en->discont, byterange_mode,
|
||||
en->duration, hls->flags & HLS_ROUND_DURATIONS,
|
||||
en->size, en->pos, vs->baseurl,
|
||||
en->filename, prog_date_time_p, en->keyframe_size, en->keyframe_pos, hls->flags & HLS_I_FRAMES_ONLY);
|
||||
@ -1519,7 +1522,7 @@ static int hls_window(AVFormatContext *s, int last, VariantStream *vs)
|
||||
}
|
||||
|
||||
if (last && (hls->flags & HLS_OMIT_ENDLIST)==0)
|
||||
ff_hls_write_end_list((byterange_mode || hls->segment_type == SEGMENT_TYPE_FMP4) ? hls->m3u8_out : oc->pb);
|
||||
ff_hls_write_end_list((byterange_mode || hls->segment_type == SEGMENT_TYPE_FMP4) ? hls->m3u8_out : vs->out);
|
||||
|
||||
if (vs->vtt_m3u8_name) {
|
||||
snprintf(temp_vtt_filename, sizeof(temp_vtt_filename), use_temp_file ? "%s.tmp" : "%s", vs->vtt_m3u8_name);
|
||||
@ -1546,7 +1549,7 @@ static int hls_window(AVFormatContext *s, int last, VariantStream *vs)
|
||||
|
||||
fail:
|
||||
av_dict_free(&options);
|
||||
hlsenc_io_close(s, (byterange_mode || hls->segment_type == SEGMENT_TYPE_FMP4) ? &hls->m3u8_out : &oc->pb, temp_filename);
|
||||
hlsenc_io_close(s, (byterange_mode || hls->segment_type == SEGMENT_TYPE_FMP4) ? &hls->m3u8_out : &vs->out, temp_filename);
|
||||
hlsenc_io_close(s, &hls->sub_m3u8_out, vs->vtt_m3u8_name);
|
||||
if (use_temp_file) {
|
||||
ff_rename(temp_filename, vs->m3u8_name, s);
|
||||
@ -1694,42 +1697,13 @@ static int hls_start(AVFormatContext *s, VariantStream *vs)
|
||||
}
|
||||
c->encrypt_started = 1;
|
||||
}
|
||||
if ((err = av_dict_set(&options, "encryption_key", c->key_string, 0))
|
||||
< 0)
|
||||
goto fail;
|
||||
err = av_strlcpy(iv_string, c->iv_string, sizeof(iv_string));
|
||||
if (!err)
|
||||
if (!err) {
|
||||
snprintf(iv_string, sizeof(iv_string), "%032"PRIx64, vs->sequence);
|
||||
if ((err = av_dict_set(&options, "encryption_iv", iv_string, 0)) < 0)
|
||||
goto fail;
|
||||
|
||||
filename = av_asprintf("crypto:%s", oc->url);
|
||||
if (!filename) {
|
||||
err = AVERROR(ENOMEM);
|
||||
goto fail;
|
||||
}
|
||||
err = hlsenc_io_open(s, &oc->pb, filename, &options);
|
||||
av_free(filename);
|
||||
av_dict_free(&options);
|
||||
if (err < 0)
|
||||
return err;
|
||||
} else if (c->segment_type != SEGMENT_TYPE_FMP4) {
|
||||
if ((err = hlsenc_io_open(s, &oc->pb, oc->url, &options)) < 0) {
|
||||
if (c->ignore_io_errors)
|
||||
err = 0;
|
||||
goto fail;
|
||||
memset(c->iv_string, 0, sizeof(c->iv_string));
|
||||
memcpy(c->iv_string, iv_string, sizeof(iv_string));
|
||||
}
|
||||
}
|
||||
if (vs->vtt_basename) {
|
||||
set_http_options(s, &options, c);
|
||||
if ((err = hlsenc_io_open(s, &vtt_oc->pb, vtt_oc->url, &options)) < 0) {
|
||||
if (c->ignore_io_errors)
|
||||
err = 0;
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
av_dict_free(&options);
|
||||
|
||||
if (c->segment_type != SEGMENT_TYPE_FMP4) {
|
||||
/* We only require one PAT/PMT per segment. */
|
||||
if (oc->oformat->priv_class && oc->priv_data) {
|
||||
@ -1741,7 +1715,23 @@ static int hls_start(AVFormatContext *s, VariantStream *vs)
|
||||
av_opt_set(oc->priv_data, "sdt_period", period, 0);
|
||||
av_opt_set(oc->priv_data, "pat_period", period, 0);
|
||||
}
|
||||
if (c->flags & HLS_SINGLE_FILE) {
|
||||
if ((err = hlsenc_io_open(s, &vs->out, oc->url, &options)) < 0) {
|
||||
if (c->ignore_io_errors)
|
||||
err = 0;
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (vs->vtt_basename) {
|
||||
set_http_options(s, &options, c);
|
||||
if ((err = hlsenc_io_open(s, &vtt_oc->pb, vtt_oc->url, &options)) < 0) {
|
||||
if (c->ignore_io_errors)
|
||||
err = 0;
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
av_dict_free(&options);
|
||||
|
||||
if (vs->vtt_basename) {
|
||||
err = avformat_write_header(vtt_oc,NULL);
|
||||
@ -2343,20 +2333,12 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt)
|
||||
int64_t new_start_pos;
|
||||
int byterange_mode = (hls->flags & HLS_SINGLE_FILE) || (hls->max_seg_size > 0);
|
||||
|
||||
av_write_frame(vs->avf, NULL); /* Flush any buffered data */
|
||||
|
||||
new_start_pos = avio_tell(vs->avf->pb);
|
||||
|
||||
if (hls->segment_type != SEGMENT_TYPE_FMP4) {
|
||||
avio_flush(oc->pb);
|
||||
vs->size = new_start_pos - vs->start_pos;
|
||||
} else {
|
||||
vs->size = new_start_pos;
|
||||
}
|
||||
|
||||
av_write_frame(oc, NULL); /* Flush any buffered data */
|
||||
new_start_pos = avio_tell(oc->pb);
|
||||
vs->size = new_start_pos - vs->start_pos;
|
||||
avio_flush(oc->pb);
|
||||
if (hls->segment_type == SEGMENT_TYPE_FMP4) {
|
||||
if (!vs->init_range_length) {
|
||||
avio_flush(oc->pb);
|
||||
range_length = avio_close_dyn_buf(oc->pb, &buffer);
|
||||
avio_write(vs->out, buffer, range_length);
|
||||
av_free(buffer);
|
||||
@ -2365,14 +2347,10 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt)
|
||||
vs->packets_written = 0;
|
||||
vs->start_pos = range_length;
|
||||
if (!byterange_mode) {
|
||||
ff_format_io_close(s, &vs->out);
|
||||
// ff_format_io_close(s, &vs->out);
|
||||
hlsenc_io_close(s, &vs->out, vs->base_output_dirname);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!byterange_mode) {
|
||||
hlsenc_io_close(s, &oc->pb, oc->url);
|
||||
}
|
||||
}
|
||||
if (!byterange_mode) {
|
||||
if (vs->vtt_avf) {
|
||||
@ -2387,32 +2365,44 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt)
|
||||
|
||||
// look to rename the asset name
|
||||
if (use_temp_file) {
|
||||
if (!(hls->flags & HLS_SINGLE_FILE) || (hls->max_seg_size <= 0))
|
||||
if ((vs->avf->oformat->priv_class && vs->avf->priv_data) && hls->segment_type != SEGMENT_TYPE_FMP4)
|
||||
av_opt_set(vs->avf->priv_data, "mpegts_flags", "resend_headers", 0);
|
||||
av_dict_set(&options, "mpegts_flags", "resend_headers", 0);
|
||||
}
|
||||
|
||||
if (hls->segment_type == SEGMENT_TYPE_FMP4) {
|
||||
if (hls->flags & HLS_SINGLE_FILE) {
|
||||
ret = flush_dynbuf(vs, &range_length);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
if (hls->flags & HLS_SINGLE_FILE) {
|
||||
ret = flush_dynbuf(vs, &range_length);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
vs->size = range_length;
|
||||
} else {
|
||||
set_http_options(s, &options, hls);
|
||||
if ((hls->max_seg_size > 0 && (vs->size >= hls->max_seg_size)) || !byterange_mode) {
|
||||
char *filename = NULL;
|
||||
if (hls->key_info_file || hls->encrypt) {
|
||||
av_dict_set(&options, "encryption_key", hls->key_string, 0);
|
||||
av_dict_set(&options, "encryption_iv", hls->iv_string, 0);
|
||||
filename = av_asprintf("crypto:%s", oc->url);
|
||||
} else {
|
||||
filename = av_asprintf("%s", oc->url);
|
||||
}
|
||||
vs->size = range_length;
|
||||
} else {
|
||||
set_http_options(s, &options, hls);
|
||||
ret = hlsenc_io_open(s, &vs->out, vs->avf->url, &options);
|
||||
if (!filename) {
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
ret = hlsenc_io_open(s, &vs->out, filename, &options);
|
||||
if (ret < 0) {
|
||||
av_log(s, hls->ignore_io_errors ? AV_LOG_WARNING : AV_LOG_ERROR,
|
||||
"Failed to open file '%s'\n", vs->avf->url);
|
||||
"Failed to open file '%s'\n", filename);
|
||||
return hls->ignore_io_errors ? 0 : ret;
|
||||
}
|
||||
write_styp(vs->out);
|
||||
if (hls->segment_type == SEGMENT_TYPE_FMP4) {
|
||||
write_styp(vs->out);
|
||||
}
|
||||
ret = flush_dynbuf(vs, &range_length);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
ff_format_io_close(s, &vs->out);
|
||||
hlsenc_io_close(s, &vs->out, filename);
|
||||
av_free(filename);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2420,7 +2410,7 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt)
|
||||
hls_rename_temp_file(s, oc);
|
||||
}
|
||||
|
||||
old_filename = av_strdup(vs->avf->url);
|
||||
old_filename = av_strdup(oc->url);
|
||||
if (!old_filename) {
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
@ -2435,11 +2425,6 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt)
|
||||
}
|
||||
}
|
||||
|
||||
if (hls->segment_type != SEGMENT_TYPE_FMP4) {
|
||||
vs->start_pos = new_start_pos;
|
||||
} else {
|
||||
vs->start_pos += vs->size;
|
||||
}
|
||||
// if we're building a VOD playlist, skip writing the manifest multiple times, and just wait until the end
|
||||
if (hls->pl_type != PLAYLIST_TYPE_VOD) {
|
||||
if ((ret = hls_window(s, 0, vs)) < 0) {
|
||||
@ -2449,8 +2434,10 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt)
|
||||
|
||||
if (hls->flags & HLS_SINGLE_FILE) {
|
||||
vs->number++;
|
||||
vs->start_pos += vs->size;
|
||||
} else if (hls->max_seg_size > 0) {
|
||||
if (vs->start_pos >= hls->max_seg_size) {
|
||||
vs->start_pos = new_start_pos;
|
||||
if (vs->size >= hls->max_seg_size) {
|
||||
vs->sequence++;
|
||||
sls_flag_file_rename(hls, vs, old_filename);
|
||||
ret = hls_start(s, vs);
|
||||
@ -2461,6 +2448,7 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt)
|
||||
}
|
||||
vs->number++;
|
||||
} else {
|
||||
vs->start_pos = new_start_pos;
|
||||
sls_flag_file_rename(hls, vs, old_filename);
|
||||
ret = hls_start(s, vs);
|
||||
}
|
||||
@ -2475,13 +2463,12 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt)
|
||||
vs->packets_written++;
|
||||
if (oc->pb) {
|
||||
ret = ff_write_chained(oc, stream_index, pkt, s, 0);
|
||||
vs->video_keyframe_size += pkt->size;
|
||||
if ((st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) && (pkt->flags & AV_PKT_FLAG_KEY)) {
|
||||
vs->video_keyframe_size = avio_tell(oc->pb) - vs->video_lastpos;
|
||||
vs->video_keyframe_pos = vs->start_pos;
|
||||
vs->video_keyframe_size = avio_tell(oc->pb);
|
||||
} else {
|
||||
vs->video_lastpos = avio_tell(oc->pb);
|
||||
vs->video_keyframe_pos = avio_tell(vs->out);
|
||||
}
|
||||
|
||||
if (hls->ignore_io_errors)
|
||||
ret = 0;
|
||||
}
|
||||
@ -2530,10 +2517,12 @@ static int hls_write_trailer(struct AVFormatContext *s)
|
||||
int i;
|
||||
int ret = 0;
|
||||
VariantStream *vs = NULL;
|
||||
AVDictionary *options = NULL;
|
||||
int range_length, byterange_mode;
|
||||
|
||||
for (i = 0; i < hls->nb_varstreams; i++) {
|
||||
char *filename = NULL;
|
||||
vs = &hls->var_streams[i];
|
||||
|
||||
oc = vs->avf;
|
||||
vtt_oc = vs->vtt_avf;
|
||||
old_filename = av_strdup(vs->avf->url);
|
||||
@ -2542,11 +2531,22 @@ static int hls_write_trailer(struct AVFormatContext *s)
|
||||
if (!old_filename) {
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
if (hls->key_info_file || hls->encrypt) {
|
||||
av_dict_set(&options, "encryption_key", hls->key_string, 0);
|
||||
av_dict_set(&options, "encryption_iv", hls->iv_string, 0);
|
||||
filename = av_asprintf("crypto:%s", vs->avf->url);
|
||||
} else {
|
||||
filename = av_asprintf("%s", vs->avf->url);
|
||||
}
|
||||
if (!filename) {
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
|
||||
|
||||
if ( hls->segment_type == SEGMENT_TYPE_FMP4) {
|
||||
int range_length = 0;
|
||||
if (!vs->init_range_length) {
|
||||
uint8_t *buffer = NULL;
|
||||
int range_length, byterange_mode;
|
||||
av_write_frame(vs->avf, NULL); /* Flush any buffered data */
|
||||
avio_flush(oc->pb);
|
||||
|
||||
@ -2563,21 +2563,25 @@ static int hls_write_trailer(struct AVFormatContext *s)
|
||||
hlsenc_io_close(s, &vs->out, vs->base_output_dirname);
|
||||
}
|
||||
}
|
||||
if (!(hls->flags & HLS_SINGLE_FILE)) {
|
||||
ret = hlsenc_io_open(s, &vs->out, vs->avf->url, NULL);
|
||||
if (ret < 0) {
|
||||
av_log(s, AV_LOG_ERROR, "Failed to open file '%s'\n", vs->avf->url);
|
||||
goto failed;
|
||||
}
|
||||
write_styp(vs->out);
|
||||
}
|
||||
ret = flush_dynbuf(vs, &range_length);
|
||||
}
|
||||
if (!(hls->flags & HLS_SINGLE_FILE)) {
|
||||
set_http_options(s, &options, hls);
|
||||
ret = hlsenc_io_open(s, &vs->out, filename, &options);
|
||||
if (ret < 0) {
|
||||
av_log(s, AV_LOG_ERROR, "Failed to open file '%s'\n", vs->avf->url);
|
||||
goto failed;
|
||||
}
|
||||
vs->size = range_length;
|
||||
ff_format_io_close(s, &vs->out);
|
||||
if (hls->segment_type == SEGMENT_TYPE_FMP4)
|
||||
write_styp(vs->out);
|
||||
}
|
||||
ret = flush_dynbuf(vs, &range_length);
|
||||
if (ret < 0)
|
||||
goto failed;
|
||||
|
||||
vs->size = range_length;
|
||||
hlsenc_io_close(s, &vs->out, filename);
|
||||
av_free(filename);
|
||||
|
||||
|
||||
failed:
|
||||
av_write_trailer(oc);
|
||||
@ -2587,12 +2591,6 @@ failed:
|
||||
use_temp_file = proto && !strcmp(proto, "file") && (hls->flags & HLS_TEMP_FILE);
|
||||
}
|
||||
|
||||
if (oc->pb) {
|
||||
if (hls->segment_type != SEGMENT_TYPE_FMP4) {
|
||||
vs->size = avio_tell(vs->avf->pb) - vs->start_pos;
|
||||
hlsenc_io_close(s, &vs->avf->pb, vs->avf->url);
|
||||
}
|
||||
|
||||
// rename that segment from .tmp to the real one
|
||||
if (use_temp_file && !(hls->flags & HLS_SINGLE_FILE)) {
|
||||
hls_rename_temp_file(s, oc);
|
||||
@ -2606,7 +2604,6 @@ failed:
|
||||
|
||||
/* after av_write_trailer, then duration + 1 duration per packet */
|
||||
hls_append_segment(s, hls, vs, vs->duration + vs->dpp, vs->start_pos, vs->size);
|
||||
}
|
||||
|
||||
sls_flag_file_rename(hls, vs, old_filename);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user