fixed choppy audio in HLS: added hls_muxdelay directive

This commit is contained in:
Roman Arutyunyan 2012-08-17 18:55:59 +04:00
parent ecb6462d56
commit 2bd3d17fbb

View file

@ -58,6 +58,7 @@ typedef struct {
unsigned opened:1;
unsigned audio:1;
unsigned video:1;
unsigned header_sent:1;
ngx_str_t playlist;
ngx_str_t playlist_bak;
@ -78,6 +79,7 @@ typedef struct {
typedef struct {
ngx_flag_t hls;
ngx_msec_t fraglen;
ngx_msec_t muxdelay;
ngx_msec_t playlen;
size_t nfrags;
ngx_rtmp_hls_ctx_t **ctx;
@ -116,6 +118,14 @@ static ngx_command_t ngx_rtmp_hls_commands[] = {
offsetof(ngx_rtmp_hls_app_conf_t, playlen),
NULL },
{ ngx_string("hls_muxdelay"),
NGX_RTMP_MAIN_CONF|NGX_RTMP_SRV_CONF|NGX_RTMP_APP_CONF|NGX_CONF_TAKE1,
ngx_conf_set_msec_slot,
NGX_RTMP_APP_CONF_OFFSET,
offsetof(ngx_rtmp_hls_app_conf_t, muxdelay),
NULL },
ngx_null_command
};
@ -262,7 +272,7 @@ ngx_rtmp_hls_init_video(ngx_rtmp_session_t *s)
stream->codec->codec_id = CODEC_ID_H264;
stream->codec->codec_type = AVMEDIA_TYPE_VIDEO;
stream->codec->pix_fmt = PIX_FMT_YUV420P;
stream->codec->time_base.den = 1;
stream->codec->time_base.den = 25;
stream->codec->time_base.num = 1;
stream->codec->width = 100;
stream->codec->height = 100;
@ -316,7 +326,7 @@ ngx_rtmp_hls_init_audio(ngx_rtmp_session_t *s)
stream->codec->sample_fmt = (codec_ctx->sample_size == 1 ?
AV_SAMPLE_FMT_U8 : AV_SAMPLE_FMT_S16);
stream->codec->sample_rate = 48000;/*codec_ctx->sample_rate;*/
stream->codec->bit_rate = 128000;
stream->codec->bit_rate = 2000000;
stream->codec->channels = codec_ctx->audio_channels;
ctx->out_astream = stream->index;
@ -406,8 +416,10 @@ static ngx_int_t
ngx_rtmp_hls_initialize(ngx_rtmp_session_t *s)
{
ngx_rtmp_hls_ctx_t *ctx;
ngx_rtmp_hls_app_conf_t *hacf;
AVOutputFormat *format;
hacf = ngx_rtmp_get_module_app_conf(s, ngx_rtmp_hls_module);
ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_hls_module);
if (ctx == NULL || ctx->out_format || ctx->publishing == 0) {
return NGX_OK;
@ -430,6 +442,7 @@ ngx_rtmp_hls_initialize(ngx_rtmp_session_t *s)
return NGX_ERROR;
}
ctx->out_format->oformat = format;
ctx->out_format->max_delay = (int64_t)hacf->muxdelay * AV_TIME_BASE / 1000;
return NGX_ERROR;
}
@ -449,6 +462,10 @@ ngx_rtmp_hls_open_file(ngx_rtmp_session_t *s, u_char *fpath)
return NGX_OK;
}
if (!ctx->video || !ctx->audio) {
return NGX_OK;
}
ngx_log_debug1(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
"hls: open stream file '%s'", fpath);
@ -475,11 +492,14 @@ ngx_rtmp_hls_open_file(ngx_rtmp_session_t *s, u_char *fpath)
}
/* write header */
if (avformat_write_header(ctx->out_format, NULL) < 0) {
if (!ctx->header_sent &&
avformat_write_header(ctx->out_format, NULL) < 0)
{
ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
"hls: avformat_write_header failed");
return NGX_ERROR;
}
ctx->header_sent = 1;
if (astream) {
astream->codec->extradata = NULL;
@ -651,10 +671,11 @@ ngx_rtmp_hls_close_file(ngx_rtmp_session_t *s)
ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_hls_module);
/*
if (av_write_trailer(ctx->out_format) < 0) {
ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
"hls: av_write_trailer failed");
}
}*/
avio_flush(ctx->out_format->pb);
@ -1028,10 +1049,11 @@ ngx_rtmp_hls_video(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,
packet.dts = h->timestamp * 90L;
packet.pts = packet.dts + cts * 90;
packet.stream_index = ctx->out_vstream;
/*
if (ftype == 1) {
packet.flags |= AV_PKT_FLAG_KEY;
}*/
}
packet.data = buffer;
packet.size = out.pos - buffer;
@ -1056,6 +1078,7 @@ ngx_rtmp_hls_create_app_conf(ngx_conf_t *cf)
conf->hls = NGX_CONF_UNSET;
conf->fraglen = NGX_CONF_UNSET;
conf->muxdelay = NGX_CONF_UNSET;
conf->playlen = NGX_CONF_UNSET;
conf->nbuckets = 1024;
@ -1071,6 +1094,7 @@ ngx_rtmp_hls_merge_app_conf(ngx_conf_t *cf, void *parent, void *child)
ngx_conf_merge_value(conf->hls, prev->hls, 0);
ngx_conf_merge_msec_value(conf->fraglen, prev->fraglen, 5000);
ngx_conf_merge_msec_value(conf->muxdelay, prev->muxdelay, 700);
ngx_conf_merge_msec_value(conf->playlen, prev->playlen, 30000);
ngx_conf_merge_str_value(conf->path, prev->path, "");
conf->ctx = ngx_pcalloc(cf->pool,