diff --git a/ffmpeg/encoder.c b/ffmpeg/encoder.c index 3ce1ab4527..c930b1362b 100755 --- a/ffmpeg/encoder.c +++ b/ffmpeg/encoder.c @@ -286,6 +286,8 @@ int open_output(struct output_ctx *octx, struct input_ctx *ictx) if (ret < 0) LPMS_ERR(open_output_err, "Error opening output file"); } + if (octx->metadata) av_dict_copy(&oc->metadata, octx->metadata, 0); + ret = avformat_write_header(oc, &octx->muxer->opts); if (ret < 0) LPMS_ERR(open_output_err, "Error writing header"); diff --git a/ffmpeg/ffmpeg.go b/ffmpeg/ffmpeg.go index 76c743fdb0..201f6aa161 100755 --- a/ffmpeg/ffmpeg.go +++ b/ffmpeg/ffmpeg.go @@ -112,6 +112,7 @@ type TranscodeOptions struct { Muxer ComponentOptions VideoEncoder ComponentOptions AudioEncoder ComponentOptions + Metadata map[string]string } type MediaInfo struct { @@ -778,6 +779,7 @@ func createCOutputParams(input *TranscodeOptionsIn, ps []TranscodeOptions) ([]C. name: C.CString(audioEncoder), opts: newAVOpts(p.AudioEncoder.Opts), } + metadata := newAVOpts(p.Metadata) fromMs := int(p.From.Milliseconds()) toMs := int(p.To.Milliseconds()) vfilt := C.CString(filters) @@ -786,7 +788,7 @@ func createCOutputParams(input *TranscodeOptionsIn, ps []TranscodeOptions) ([]C. params[i] = C.output_params{fname: oname, fps: fps, w: C.int(w), h: C.int(h), bitrate: C.int(bitrate), gop_time: C.int(gopMs), from: C.int(fromMs), to: C.int(toMs), - muxer: muxOpts, audio: audioOpts, video: vidOpts, + muxer: muxOpts, audio: audioOpts, video: vidOpts, metadata: metadata, vfilters: vfilt, sfilters: nil, xcoderParams: xcoderOutParams} if p.CalcSign { //signfilter string @@ -841,6 +843,9 @@ func destroyCOutputParams(params []C.output_params) { if p.video.opts != nil { C.av_dict_free(&p.video.opts) } + if p.metadata != nil { + C.av_dict_free(&p.metadata) + } } } diff --git a/ffmpeg/ffmpeg_test.go b/ffmpeg/ffmpeg_test.go index 93e184b9cc..14bdd67da9 100644 --- a/ffmpeg/ffmpeg_test.go +++ b/ffmpeg/ffmpeg_test.go @@ -1628,6 +1628,9 @@ func TestTranscoder_FormatOptions(t *testing.T) { Oname: dir + "/test.flv", VideoEncoder: ComponentOptions{Name: "copy"}, AudioEncoder: ComponentOptions{Name: "copy"}, + Metadata: map[string]string{ + "encoded_by": "Livepeer Media Server", + }, }} if out[0].Profile.Format != FormatNone { t.Error("Expected empty profile for output option") @@ -1637,7 +1640,7 @@ func TestTranscoder_FormatOptions(t *testing.T) { t.Error(err) } cmd = ` - ffprobe -loglevel warning -show_format test.flv | grep format_name=flv + ffprobe -loglevel warning -show_format test.flv | grep 'format_name=flv\|encoded_by=Livepeer Media Server' ` run(cmd) @@ -1646,6 +1649,9 @@ func TestTranscoder_FormatOptions(t *testing.T) { out[0].Muxer = ComponentOptions{Name: "hls", Opts: map[string]string{ "hls_segment_filename": dir + "/test_segment_%d.ts", }} + out[0].Metadata = map[string]string{ + "service_provider": "Livepeer Media Server", + } _, err = Transcode3(in, out) if err != nil { t.Error(err) @@ -1660,6 +1666,7 @@ func TestTranscoder_FormatOptions(t *testing.T) { ffprobe -loglevel warning -show_entries format=format_name,duration test.ts > test.out diff -u segment.out test.out wc -l test.out | grep 4 # sanity check output file length + ffprobe segment.ts 2>&1 | grep 'service_provider: Livepeer Media Server' ` run(cmd) diff --git a/ffmpeg/filter.h b/ffmpeg/filter.h index 59d9e8c945..412f185d0f 100755 --- a/ffmpeg/filter.h +++ b/ffmpeg/filter.h @@ -65,6 +65,7 @@ struct output_ctx { component_opts *muxer; component_opts *video; component_opts *audio; + AVDictionary *metadata; int64_t drop_ts; // preroll audio ts to drop diff --git a/ffmpeg/transcoder.c b/ffmpeg/transcoder.c index dfc0807aa5..b27a7e02e5 100755 --- a/ffmpeg/transcoder.c +++ b/ffmpeg/transcoder.c @@ -216,6 +216,7 @@ int transcode_init(struct transcode_thread *h, input_params *inp, octx->muxer = ¶ms[i].muxer; octx->audio = ¶ms[i].audio; octx->video = ¶ms[i].video; + octx->metadata = params[i].metadata; octx->vfilters = params[i].vfilters; octx->sfilters = params[i].sfilters; octx->xcoderParams = params[i].xcoderParams; diff --git a/ffmpeg/transcoder.h b/ffmpeg/transcoder.h index 8c1c4888b4..e0cca743b4 100755 --- a/ffmpeg/transcoder.h +++ b/ffmpeg/transcoder.h @@ -35,6 +35,7 @@ typedef struct { component_opts muxer; component_opts audio; component_opts video; + AVDictionary *metadata; } output_params; typedef struct {