public void GenerateDash_MidLevelApiOptions_ProducesCorrectDashEncodeResult() { Encoder encoder = new Encoder(ffmpegPath, ffprobePath, mp4boxPath, ffmpegCommandGenerator: (dashConfig, mediaMetadata) => { DashConfig c = dashConfig; MediaMetadata m = mediaMetadata; FFmpegCommand r = Encoder.GenerateFFmpegCommand(c, m); return(r); }, mp4BoxCommandGenerator: (dashConfig, videoStreams, audioStreams) => { DashConfig c = dashConfig; IEnumerable <VideoStreamCommand> v = videoStreams; IEnumerable <AudioStreamCommand> a = audioStreams; Mp4BoxCommand r = Encoder.GenerateMp4BoxCommand(c, v, a); return(r); }); DashConfig config = new DashConfig(testFileName, RunPath, Qualities, "output"); encodeResult = encoder.GenerateDash(config, encoder.ProbeFile(config.InputFilePath, out _)); Assert.NotNull(encodeResult.DashFilePath); Assert.NotNull(encodeResult.DashFileContent); Assert.NotNull(encodeResult.MediaFiles); Assert.Equal(4, encodeResult.MediaFiles.Count()); }
public void TestMultipleTrack() { TestCleanup((results) => { string runPath = Path.Combine(Environment.CurrentDirectory, @"..\..\..\"); Encoder c = new Encoder(); c.EnableStreamCopying = true; DashEncodeResult s = c.GenerateDash( inFile: Path.Combine(runPath, "test5.mkv"), outFilename: "outputmulti#&*<>/?:\"1", framerate: 30, keyframeInterval: 90, qualities: new List <Quality> { new Quality(1280, 720, 9000, "ultrafast"), new Quality(640, 480, 768, "ultrafast"), }, outDirectory: runPath); results.Add(s); Assert.NotNull(s.DashFilePath); Assert.NotNull(s.DashFileContent); Assert.NotNull(s.MediaFiles); Assert.Equal(15, s.MediaFiles.Count()); Assert.Contains("outputmulti1_audio_default_1_dashinit.mp4", s.MediaFiles); Assert.Contains("outputmulti1_subtitle_eng_2.vtt", s.MediaFiles); Assert.Contains("outputmulti1_subtitle_und_10.vtt", s.MediaFiles); Assert.Contains("outputmulti1_subtitle_eng_12.vtt", s.MediaFiles); }); }
public void GenerateDash_Downmixing_ProducesCorrectDashEncodeResult() { Encoder encoder = new Encoder(ffmpegPath, ffprobePath, mp4boxPath); DashConfig config = new DashConfig(multiLanguageTestFileName, RunPath, Qualities, "output") { AudioConfig = new AudioConfig() { DownmixMode = DownmixMode.Default, MaxPerChannelBitrate = 1024 * 80 } }; encodeResult = encoder.GenerateDash(config, encoder.ProbeFile(config.InputFilePath, out _)); var scans = encodeResult.MediaFiles.Select((x) => encoder.ProbeFile(x, out _)); foreach (var outputStream in scans) { if (outputStream.VideoStreams.Count() > 0) { continue; } foreach (var aStream in outputStream.AudioStreams) { Assert.True(aStream.channels <= 2); Assert.True(aStream.max_bit_rate <= config.AudioConfig.MaxPerChannelBitrate * aStream.channels); } } }
public void GenerateDash_WithLiveStreamingProfile_ProducesCorrectDashEncodeResult() { string outputFilename = "outputlive"; var options = new H264EncodeOptions { AdditionalMP4BoxFlags = new List <string>() { "-profile \"dashavc264:live\"", "-bs-switching no" } }; Encoder encoder = new Encoder(ffmpegPath, ffprobePath, mp4boxPath); DashConfig config = new DashConfig("testfile.ogg", RunPath, SubtitleQualities, outputFilename) { Options = options }; try { encodeResult = encoder.GenerateDash(config, encoder.ProbeFile(config.InputFilePath, out _)); Assert.NotNull(encodeResult.DashFilePath); Assert.NotNull(encodeResult.DashFileContent); } finally { foreach (var file in Directory.EnumerateFiles(RunPath, $"{outputFilename}_*")) { File.Delete(Path.Combine(RunPath, file)); } } }
public void TestGenerateMpd() { TestCleanup((results) => { string runPath = Path.Combine(Environment.CurrentDirectory, @"..\..\..\"); IEnumerable <EncodeStageProgress> progress = null; Encoder c = new Encoder(); DashEncodeResult s = c.GenerateDash( inFile: Path.Combine(runPath, "testfile.ogg"), outFilename: "output", framerate: 30, keyframeInterval: 90, qualities: new List <Quality> { new Quality(1920, 1080, 4000, "fast"), new Quality(1280, 720, 1280, "fast"), new Quality(640, 480, 768, "fast"), }, outDirectory: runPath, progress: new NaiveProgress <IEnumerable <EncodeStageProgress> >(x => { progress = x; })); results.Add(s); Assert.NotNull(s.DashFilePath); Assert.NotNull(s.DashFileContent); Assert.NotNull(s.MediaFiles); Assert.Equal(4, s.MediaFiles.Count()); Assert.Equal(1.0, progress.Where(x => x.Name == "Encode").Select(y => y.Progress).Single()); Assert.Equal(1.0, progress.Where(x => x.Name == "DASHify").Select(y => y.Progress).Single()); Assert.Equal(1.0, progress.Where(x => x.Name == "Post Process").Select(y => y.Progress).Single()); }); }
public void TestMultipleLanguage() { TestCleanup((results) => { string runPath = Path.Combine(Environment.CurrentDirectory, @"..\..\..\"); Encoder c = new Encoder(); c.EnableStreamCopying = true; DashEncodeResult s = c.GenerateDash( inFile: Path.Combine(runPath, "testlang.mp4"), outFilename: "outputlang", framerate: 30, keyframeInterval: 90, qualities: new List <Quality> { new Quality(640, 480, 768, "ultrafast"), }, outDirectory: runPath); results.Add(s); Assert.NotNull(s.DashFilePath); Assert.NotNull(s.DashFileContent); Assert.NotNull(s.MediaFiles); Assert.Equal("avc1.640028", s.DashFileContent.Period[0].AdaptationSet[0].Representation[0].Codecs); Assert.True(s.DashFileContent.Period[0].AdaptationSet.Where(x => x.Lang == "jpn" && x.MaxFrameRate == null).SingleOrDefault().Representation.Count() == 1); Assert.True(s.DashFileContent.Period[0].AdaptationSet.Where(x => x.Lang == "eng" && x.MaxFrameRate == null).SingleOrDefault().Representation.Count() == 2); }); }
private static void RunWithOptions(Options options) { string workingDirectory = options.TempDir ?? Environment.CurrentDirectory; string outputPath = options.OutputPath ?? Path.GetDirectoryName(Path.GetFullPath(options.InputFile)); string outputName = options.OutputFilename ?? Path.GetFileNameWithoutExtension(options.InputFile); if (!File.Exists(options.InputFile)) { Console.Error.WriteLine("Input file doesn't exist."); return; } var outputCallback = new Action <string>((x) => { Console.WriteLine(x); }); var errorCallback = new Action <string>((x) => { Console.Error.WriteLine(x); }); var encoder = new Encoder(options.FFmpegPath, options.FFprobePath, options.BoxPath, outputCallback, errorCallback, workingDirectory) { DisableQualityCrushing = options.DisableCrushing, EnableStreamCopying = !options.DisableStreamCopying }; var qualities = Quality.GenerateDefaultQualities(options.Quality, options.Preset); var progress = new Progress <IEnumerable <EncodeStageProgress> >(WriteProgress); DashEncodeResult result = null; try { running = true; result = encoder.GenerateDash( options.InputFile, outputName, options.Framerate, options.KeyInterval, qualities, outDirectory: outputPath, cancel: cancelToken.Token, progress: progress); } finally { running = false; } if (result != null) { HandleDelete(options.DeleteBehavior, options.InputFile); Console.WriteLine("MPD Generated: " + result.DashFilePath); Console.WriteLine("Media files:"); Console.Write(string.Join('\n', result.MediaFiles)); Environment.Exit(0); } Console.Error.WriteLine("Failed to produce files. Exiting..."); Environment.Exit(3); }
public void GenerateDash_WithCancellationToken_ThrowsOperationCanceledException() { var tokenSource = new CancellationTokenSource(500); DEnc.Encoder encoder = new DEnc.Encoder(ffmpegPath, ffprobePath, mp4boxPath); DashConfig config = new DashConfig(testFileName, RunPath, Qualities, "output"); Assert.Throws <OperationCanceledException>(() => encodeResult = encoder.GenerateDash(config, cancel: tokenSource.Token)); }
public void GenerateDash_NormalEncode_ProducesCorrectDashEncodeResult() { Encoder encoder = new Encoder(ffmpegPath, ffprobePath, mp4boxPath); DashConfig config = new DashConfig(testFileName, RunPath, Qualities, "output"); encodeResult = encoder.GenerateDash(config, encoder.ProbeFile(config.InputFilePath, out _)); Assert.NotNull(encodeResult.DashFilePath); Assert.NotNull(encodeResult.DashFileContent); Assert.NotNull(encodeResult.MediaFiles); Assert.Equal(4, encodeResult.MediaFiles.Count()); }
public void TestMP4BoxLiveProfile() { TestCleanup((results) => { string runPath = Path.Combine(Environment.CurrentDirectory, @"..\..\..\"); string filename = "outputlive"; try { IEnumerable <EncodeStageProgress> progress = null; var options = new H264EncodeOptions { AdditionalMP4BoxFlags = new List <string>() { "-profile \"dashavc264:live\"", "-bs-switching no" } }; Encoder c = new Encoder(); DashEncodeResult s = c.GenerateDash( options: options, inFile: Path.Combine(runPath, "testfile.ogg"), outFilename: filename, framerate: 30, keyframeInterval: 90, qualities: new List <Quality> { new Quality(1280, 720, 1280, "fast"), new Quality(640, 480, 768, "fast"), }, outDirectory: runPath, progress: new NaiveProgress <IEnumerable <EncodeStageProgress> >(x => { progress = x; })); results.Add(s); Assert.NotNull(s.DashFilePath); Assert.NotNull(s.DashFileContent); Assert.Equal(1.0, progress.Where(x => x.Name == "Encode").Select(y => y.Progress).Single()); Assert.Equal(1.0, progress.Where(x => x.Name == "DASHify").Select(y => y.Progress).Single()); Assert.Equal(1.0, progress.Where(x => x.Name == "Post Process").Select(y => y.Progress).Single()); } finally { foreach (var file in Directory.EnumerateFiles(runPath, $"{filename}_*")) { File.Delete(Path.Combine(runPath, file)); } } }); }
public void GenerateDash_WithManySubtitleLanguages_ProducesSubtitleFiles() { DEnc.Encoder encoder = new DEnc.Encoder(ffmpegPath, ffprobePath, mp4boxPath); encoder.EnableStreamCopying = true; DashConfig config = new DashConfig(multiLanguageTestFileName, RunPath, MultiLanguageQualities, "outputlang"); encodeResult = encoder.GenerateDash(config); Assert.NotNull(encodeResult.DashFilePath); Assert.NotNull(encodeResult.DashFileContent); Assert.NotNull(encodeResult.MediaFiles); Assert.Equal("avc1.640028", encodeResult.DashFileContent.Period[0].AdaptationSet[0].Representation[0].Codecs); Assert.True(encodeResult.DashFileContent.Period[0].AdaptationSet.Where(x => x.Lang == "jpn" && x.MaxFrameRate == null).SingleOrDefault().Representation.Count() == 1); Assert.True(encodeResult.DashFileContent.Period[0].AdaptationSet.Where(x => x.Lang == "eng" && x.MaxFrameRate == null).Count() == 2); }
public void GenerateDash_WithManySubtitles_ProducesSubtitleFiles() { Encoder encoder = new Encoder(ffmpegPath, ffprobePath, mp4boxPath); DashConfig config = new DashConfig(subtitleTestFileName, RunPath, SubtitleQualities, "outputmulti"); encodeResult = encoder.GenerateDash(config, encoder.ProbeFile(config.InputFilePath, out _)); Assert.NotNull(encodeResult.DashFilePath); Assert.NotNull(encodeResult.DashFileContent); Assert.NotNull(encodeResult.MediaFiles); Assert.Equal(16, encodeResult.MediaFiles.Count()); Assert.Contains("outputmulti_audio_default_1_dashinit.mp4", encodeResult.MediaFiles); Assert.Contains("outputmulti_subtitle_eng_2.vtt", encodeResult.MediaFiles); Assert.Contains("outputmulti_subtitle_und_10.vtt", encodeResult.MediaFiles); Assert.Contains("outputmulti_subtitle_eng_12.vtt", encodeResult.MediaFiles); }
public void GenerateDash_WithCancellationToken_ThrowsOperationCanceledException() { var tokenSource = new CancellationTokenSource(250); Encoder encoder = new Encoder(ffmpegPath, ffprobePath, mp4boxPath); DashConfig config = new DashConfig(testFileName, RunPath, Qualities, "output"); Exception thrown = null; try { encodeResult = encoder.GenerateDash(config, encoder.ProbeFile(config.InputFilePath, out _), cancel: tokenSource.Token); } catch (Exception ex) { thrown = ex; } Assert.NotNull(thrown); Assert.IsType <OperationCanceledException>(thrown.InnerException); }
/// <summary> /// /// </summary> public PostConversionPluginArgs(ILibrary library, VolyContext context, IConversionItem item, MediaItem mediaItem, DashEncodeResult conversionResult, ConversionType type, ILogger log) { this.Library = library; this.Context = context; this.ConversionItem = item; this.MediaItem = mediaItem; this.ConversionResult = conversionResult; this.Type = type; this.Log = log; }