public MediaFile(string fileName, bool manageLifespan)
 {
     _fileName          = !Path.IsPathRooted(fileName) ? Path.GetFullPath(fileName) : fileName;
     _manageLifespan    = manageLifespan;
     _realLengthInUnits = MediaInspector.GetLength(fileName);
     _lengthUsedInUnits = _realLengthInUnits;
     LengthInFrames     = -1;
 }
Пример #2
0
 public MediaFile(string fileName, bool manageLifespan)
 {
     _manageLifespan    = manageLifespan;
     _fileName          = fileName;
     _realLengthInUnits = MediaInspector.GetLength(fileName);
     _lengthUsedInUnits = _realLengthInUnits;
     LengthInFrames     = -1;
 }
Пример #3
0
        protected void AssertLengths(double fps, string file1, string file2)
        {
            long length1 = MediaInspector.GetLength(file1);
            long length2 = MediaInspector.GetLength(file2);

            long frameLength = TimelineBuilder.ToUnits(1.0 / fps);

            long difference = Math.Abs(length1 - length2);

            Assert.IsTrue(difference <= frameLength);
        }
Пример #4
0
        protected void AssertLengths(double fps, double expected, string file)
        {
            long length1 = TimelineBuilder.ToUnits(expected);
            long length2 = MediaInspector.GetLength(file);

            long frameLength = TimelineBuilder.ToUnits(1.0 / fps) * 4; // allow for 4 frames difference

            long difference = Math.Abs(length1 - length2);

            Assert.IsTrue(difference <= frameLength,
                          string.Format("expected {0} +/- {1}, but was {2}", length1, frameLength, length2));
        }
Пример #5
0
        public async Task TestInspect()
        {
            var processRunner   = Substitute.For <IProcessRunner>();
            var processUtility  = Substitute.For <IProcessUtility>();
            var serializer      = Substitute.For <ISerializer <string> >();
            var timeout         = TimeSpan.FromMilliseconds(10);
            var ffprobeFileName = "/usr/sbin/ffprobe";
            var inspector       = new MediaInspector(ffprobeFileName, processRunner, processUtility, serializer, timeout);

            #region Test Exceptions

            await Assert.ThrowsExceptionAsync <ArgumentNullException>(async() => await inspector.Inspect(null));

            await Assert.ThrowsExceptionAsync <ArgumentException>(async() => await inspector.Inspect(string.Empty));

            #endregion

            #region Test MKV with HDR

            var fileName        = "/Users/fred/Documents/video.mkv";
            var escapedFileName = "escaped 1";
            var argPattern1     = @"-loglevel\s+error\s+-print_format\s+json\s+-show_format\s+-show_streams\s+-i\s+";
            var argPattern2     = @"-loglevel\s+error\s+-print_format\s+json\s+-show_frames\s+-select_streams\s+0\s+-read_intervals\s+%\+#1\s+-i\s+";
            var outputText      = Guid.NewGuid().ToString();
            var frameText       = Guid.NewGuid().ToString();

            processUtility.EscapeFilePath(fileName).Returns(escapedFileName);
            processRunner.Run(ffprobeFileName,
                              Arg.Is <string>(s => Regex.IsMatch(s, argPattern1 + escapedFileName)),
                              timeout)
            .Returns(new ProcessResult()
            {
                OutputData = outputText
            });
            serializer.Deserialize <Output>(outputText).Returns(FILE_OUTPUT_1);
            processRunner.Run(ffprobeFileName,
                              Arg.Is <string>(s => Regex.IsMatch(s, argPattern2 + escapedFileName)),
                              timeout)
            .Returns(new ProcessResult()
            {
                OutputData = frameText
            });
            serializer.Deserialize <FrameOutput>(frameText).Returns(FRAME_OUTPUT);

            MediaInfo info = await inspector.Inspect(fileName);

            Assert.IsNotNull(info);
            Assert.AreEqual(fileName, info.FileName);
            Assert.AreEqual("Matroska / WebM", info.FormatName);
            Assert.AreEqual(TimeSpan.FromSeconds(3186.808000), info.Duration);

            Assert.IsNotNull(info.Streams);
            Assert.AreEqual(5, info.Streams.Count);

            StreamInfo stream = info.Streams[0];

            Assert.IsNotNull(stream);
            Assert.AreEqual("hevc", stream.FormatName);
            Assert.AreEqual("eng", stream.Language);
            Assert.AreEqual(0, stream.Index);
            Assert.IsInstanceOfType(stream, typeof(VideoStreamInfo));

            var videoStream = (VideoStreamInfo)stream;

            Assert.AreEqual(new Dimensions(3840, 2160), videoStream.Dimensions);
            Assert.AreEqual(DynamicRange.High, videoStream.DynamicRange);
            Assert.AreEqual(10, videoStream.BitDepth);

            var displayProperties = videoStream.MasterDisplayProperties;

            Assert.IsNotNull(displayProperties);
            Assert.AreEqual(34000, displayProperties.Red.X);
            Assert.AreEqual(16000, displayProperties.Red.Y);
            Assert.AreEqual(13250, displayProperties.Green.X);
            Assert.AreEqual(34500, displayProperties.Green.Y);
            Assert.AreEqual(7500, displayProperties.Blue.X);
            Assert.AreEqual(3000, displayProperties.Blue.Y);
            Assert.AreEqual(15635, displayProperties.WhitePoint.X);
            Assert.AreEqual(16450, displayProperties.WhitePoint.Y);

            var lightProperties = videoStream.LightLevelProperties;

            Assert.IsNotNull(lightProperties);
            Assert.AreEqual(1000, lightProperties.MaxCll);
            Assert.AreEqual(400, lightProperties.MaxFall);

            stream = info.Streams[1];

            Assert.IsNotNull(stream);
            Assert.AreEqual("dts", stream.FormatName);
            Assert.AreEqual("eng", stream.Language);
            Assert.AreEqual(1, stream.Index);
            Assert.IsInstanceOfType(stream, typeof(AudioStreamInfo));
            Assert.AreEqual(AudioFormat.Dts, ((AudioStreamInfo)stream).Format);
            Assert.AreEqual(6, ((AudioStreamInfo)stream).ChannelCount);

            stream = info.Streams[2];

            Assert.IsNotNull(stream);
            Assert.AreEqual("dts", stream.FormatName);
            Assert.AreEqual("eng", stream.Language);
            Assert.AreEqual(2, stream.Index);
            Assert.IsInstanceOfType(stream, typeof(AudioStreamInfo));
            Assert.AreEqual(AudioFormat.Dts, ((AudioStreamInfo)stream).Format);
            Assert.AreEqual(6, ((AudioStreamInfo)stream).ChannelCount);

            stream = info.Streams[3];

            Assert.IsNotNull(stream);
            Assert.AreEqual("hdmv_pgs_subtitle", stream.FormatName);
            Assert.AreEqual("eng", stream.Language);
            Assert.AreEqual(3, stream.Index);
            Assert.IsInstanceOfType(stream, typeof(SubtitleStreamInfo));
            Assert.AreEqual(SubtitleType.Graphic, ((SubtitleStreamInfo)stream).SubtitleType);
            Assert.AreEqual(SubtitleFormat.Pgs, ((SubtitleStreamInfo)stream).Format);

            stream = info.Streams[4];

            Assert.IsNotNull(stream);
            Assert.AreEqual("subrip", stream.FormatName);
            Assert.AreEqual("eng", stream.Language);
            Assert.AreEqual(4, stream.Index);
            Assert.IsInstanceOfType(stream, typeof(SubtitleStreamInfo));
            Assert.AreEqual(SubtitleType.Text, ((SubtitleStreamInfo)stream).SubtitleType);
            Assert.AreEqual(SubtitleFormat.Subrip, ((SubtitleStreamInfo)stream).Format);

            #endregion

            #region Test MP4 with SDR

            fileName        = "/Users/fred/Documents/video.m4v";
            escapedFileName = "escaped 2";
            outputText      = Guid.NewGuid().ToString();

            processUtility.EscapeFilePath(fileName).Returns(escapedFileName);
            processRunner.Run(ffprobeFileName,
                              Arg.Is <string>(s => Regex.IsMatch(s, argPattern1 + escapedFileName)),
                              timeout)
            .Returns(new ProcessResult()
            {
                OutputData = outputText
            });
            serializer.Deserialize <Output>(outputText).Returns(FILE_OUTPUT_2);

            info = await inspector.Inspect(fileName);

            Assert.IsNotNull(info);
            Assert.AreEqual(fileName, info.FileName);
            Assert.AreEqual("QuickTime / MOV", info.FormatName);
            Assert.AreEqual(TimeSpan.FromSeconds(1597.654000), info.Duration);

            Assert.IsNotNull(info.Streams);
            Assert.AreEqual(3, info.Streams.Count);

            stream = info.Streams[0];

            Assert.IsNotNull(stream);
            Assert.AreEqual("h264", stream.FormatName);
            Assert.AreEqual("und", stream.Language);
            Assert.AreEqual(0, stream.Index);
            Assert.IsInstanceOfType(stream, typeof(VideoStreamInfo));

            videoStream = (VideoStreamInfo)stream;

            Assert.AreEqual(new Dimensions(1920, 1080), videoStream.Dimensions);
            Assert.AreEqual(DynamicRange.Standard, videoStream.DynamicRange);
            Assert.AreEqual(8, videoStream.BitDepth);
            Assert.IsNull(videoStream.MasterDisplayProperties);
            Assert.IsNull(videoStream.LightLevelProperties);

            stream = info.Streams[1];

            Assert.IsNotNull(stream);
            Assert.AreEqual("aac", stream.FormatName);
            Assert.AreEqual("eng", stream.Language);
            Assert.AreEqual(1, stream.Index);
            Assert.IsInstanceOfType(stream, typeof(AudioStreamInfo));
            Assert.AreEqual(AudioFormat.Aac, ((AudioStreamInfo)stream).Format);
            Assert.AreEqual(2, ((AudioStreamInfo)stream).ChannelCount);

            stream = info.Streams[2];

            Assert.IsNotNull(stream);
            Assert.AreEqual("ac3", stream.FormatName);
            Assert.AreEqual("eng", stream.Language);
            Assert.AreEqual(2, stream.Index);
            Assert.IsInstanceOfType(stream, typeof(AudioStreamInfo));
            Assert.AreEqual(AudioFormat.Ac3, ((AudioStreamInfo)stream).Format);
            Assert.AreEqual(6, ((AudioStreamInfo)stream).ChannelCount);

            #endregion

            #region Test MP4 with anamorphic video

            fileName        = "/Users/fred/Documents/anamorphic.m4v";
            escapedFileName = "escaped 3";
            outputText      = Guid.NewGuid().ToString();

            processUtility.EscapeFilePath(fileName).Returns(escapedFileName);
            processRunner.Run(ffprobeFileName,
                              Arg.Is <string>(s => Regex.IsMatch(s, argPattern1 + escapedFileName)),
                              timeout)
            .Returns(new ProcessResult()
            {
                OutputData = outputText
            });
            serializer.Deserialize <Output>(outputText).Returns(FILE_OUTPUT_3);

            info = await inspector.Inspect(fileName);

            Assert.IsNotNull(info);
            Assert.AreEqual(fileName, info.FileName);
            Assert.AreEqual("QuickTime / MOV", info.FormatName);
            Assert.AreEqual(TimeSpan.FromSeconds(1547.168000), info.Duration);

            Assert.IsNotNull(info.Streams);
            Assert.AreEqual(2, info.Streams.Count);

            stream = info.Streams[0];

            Assert.IsNotNull(stream);
            Assert.AreEqual("mpeg2video", stream.FormatName);
            Assert.AreEqual("und", stream.Language);
            Assert.AreEqual(0, stream.Index);
            Assert.IsInstanceOfType(stream, typeof(VideoStreamInfo));

            videoStream = (VideoStreamInfo)stream;

            Assert.AreEqual(new Dimensions(640, 480), videoStream.Dimensions);
            Assert.AreEqual(new Dimensions(720, 480), videoStream.StorageDimensions);
            Assert.AreEqual(DynamicRange.Standard, videoStream.DynamicRange);
            Assert.AreEqual(8, videoStream.BitDepth);
            Assert.IsNull(videoStream.MasterDisplayProperties);
            Assert.IsNull(videoStream.LightLevelProperties);

            stream = info.Streams[1];

            Assert.IsNotNull(stream);
            Assert.AreEqual("ac3", stream.FormatName);
            Assert.AreEqual("eng", stream.Language);
            Assert.AreEqual(1, stream.Index);
            Assert.IsInstanceOfType(stream, typeof(AudioStreamInfo));
            Assert.AreEqual(AudioFormat.Ac3, ((AudioStreamInfo)stream).Format);
            Assert.AreEqual(2, ((AudioStreamInfo)stream).ChannelCount);

            #endregion

            #region Test bad file

            fileName        = "/Users/fred/Documents/text.txt";
            escapedFileName = "bad file";

            processUtility.EscapeFilePath(fileName).Returns(escapedFileName);
            processRunner.Run(ffprobeFileName,
                              Arg.Is <string>(s => Regex.IsMatch(s, argPattern1 + escapedFileName)),
                              timeout)
            .Returns(new ProcessResult());

            info = await inspector.Inspect(fileName);

            Assert.IsNull(info);

            #endregion
        }