diff --git a/src/main/java/net/bramp/ffmpeg/builder/FFmpegOutputBuilder.java b/src/main/java/net/bramp/ffmpeg/builder/FFmpegOutputBuilder.java index 0a6b01e1..18e8c0fb 100644 --- a/src/main/java/net/bramp/ffmpeg/builder/FFmpegOutputBuilder.java +++ b/src/main/java/net/bramp/ffmpeg/builder/FFmpegOutputBuilder.java @@ -13,6 +13,7 @@ import org.apache.commons.lang3.math.Fraction; import java.util.List; +import java.util.ArrayList; import java.util.concurrent.TimeUnit; import static com.google.common.base.Preconditions.checkState; @@ -56,6 +57,7 @@ public class FFmpegOutputBuilder implements Cloneable { public String video_preset; public String video_filter; public String video_filter_complex; + public List video_meta_tags; public boolean subtitle_enabled = true; @@ -223,6 +225,24 @@ public FFmpegOutputBuilder setComplexVideoFilter(String filter) { return this; } + /** + * Allows to add metadata to output video. Which keys are possible depends on the used output + * video codec. + * + * @param key Metadata key, e.g. "comment" + * @param value Value to set for key + * @return This instance + */ + public FFmpegOutputBuilder addMetaTag(String key, String value) { + this.video_enabled = true; + if (this.video_meta_tags == null) { + this.video_meta_tags = new ArrayList<>(); + } + + this.video_meta_tags.add(checkNotNull(key) + "=" + checkNotNull(value).replace("\"", "")); + return this; + } + public FFmpegOutputBuilder setAudioCodec(String codec) { this.audio_enabled = true; this.audio_codec = checkNotNull(codec); @@ -448,6 +468,12 @@ protected List build(int pass) { args.add("-filter_complex").add(video_filter_complex); } + if (video_meta_tags != null) { + for (String meta : video_meta_tags) { + args.add("-metadata").add("\"" + meta + "\""); + } + } + } else { args.add("-vn"); } diff --git a/src/test/java/net/bramp/ffmpeg/FFmpegBuilderTest.java b/src/test/java/net/bramp/ffmpeg/FFmpegBuilderTest.java index ab3cf365..b94cfd80 100644 --- a/src/test/java/net/bramp/ffmpeg/FFmpegBuilderTest.java +++ b/src/test/java/net/bramp/ffmpeg/FFmpegBuilderTest.java @@ -109,6 +109,20 @@ public void testMultipleOutputs() { "output1", "-s", "640x480", "output2"))); } + /** + * Tests whether setting meta tags works correctly. + */ + @Test + public void testMetaTags() { + FFmpegBuilder builder = + new FFmpegBuilder().setInput("input").addOutput("output").disableAudio().disableSubtitle() + .addMetaTag("comment", "My Comment").addMetaTag("title", "\"Video\"").done(); + + List args = builder.build(); + assertThat(args, is(Arrays.asList("-y", "-v", "error", "-i", "input", "-metadata", + "\"comment=My Comment\"", "-metadata", "\"title=Video\"", "-an", "-sn", "output"))); + } + @Test(expected = IllegalArgumentException.class) public void testNothing() { FFmpegBuilder builder = new FFmpegBuilder(); diff --git a/src/test/java/net/bramp/ffmpeg/FFmpegExecutorTest.java b/src/test/java/net/bramp/ffmpeg/FFmpegExecutorTest.java index 701f6772..73bb5fc2 100644 --- a/src/test/java/net/bramp/ffmpeg/FFmpegExecutorTest.java +++ b/src/test/java/net/bramp/ffmpeg/FFmpegExecutorTest.java @@ -62,6 +62,22 @@ public void testFilter() throws InterruptedException, ExecutionException, IOExce assertEquals(FFmpegJob.State.FINISHED, job.getState()); } + @Test + public void testMetaTags() throws InterruptedException, ExecutionException, IOException { + + FFmpegBuilder builder = + new FFmpegBuilder().setInput(Samples.big_buck_bunny_720p_1mb).overrideOutputFiles(true) + .addOutput(Samples.output_mp4).setFormat("mp4").disableAudio().setVideoCodec("mpeg4") + .addMetaTag("comment", "This=Nice!").addMetaTag("title", "Big Buck Bunny").done(); + + FFmpegExecutor executor = new FFmpegExecutor(ffmpeg, ffprobe); + + FFmpegJob job = executor.createJob(builder); + runAndWait(job); + + assertEquals(FFmpegJob.State.FINISHED, job.getState()); + } + protected void runAndWait(FFmpegJob job) throws ExecutionException, InterruptedException { Future future = executor.submit(job);