示例#1
0
        private static String ConstructTrackOrder(VideoFileInfo videoFile)
        {
            List<Int32>trackNumbers = new List<Int32>(videoFile.Tracks.Count);
            videoFile.Tracks.Where(t => t.TrackType == TrackType.Video)
                .OrderBy(t => t.MkvToolsTrackNumber)
                .ToList().ForEach(t => trackNumbers.Add(t.MkvToolsTrackNumber));

            videoFile.Tracks.Where(t => t.TrackType == TrackType.Audio && t.Default == true)
                .OrderBy(t => t.MkvToolsTrackNumber)
                .ToList().ForEach(t => trackNumbers.Add(t.MkvToolsTrackNumber));
            videoFile.Tracks.Where(t => t.TrackType == TrackType.Audio && t.Default == false)
                .OrderBy(t => t.MkvToolsTrackNumber)
                .ToList().ForEach(t => trackNumbers.Add(t.MkvToolsTrackNumber));

            videoFile.Tracks.Where(t => t.TrackType == TrackType.Subtitle && t.Default == true)
                .OrderBy(t => t.MkvToolsTrackNumber)
                .ToList().ForEach(t => trackNumbers.Add(t.MkvToolsTrackNumber));
            videoFile.Tracks.Where(t => t.TrackType == TrackType.Subtitle && t.Default == false)
                .OrderBy(t => t.MkvToolsTrackNumber)
                .ToList().ForEach(t => trackNumbers.Add(t.MkvToolsTrackNumber));

            videoFile.Tracks.Where(t => t.TrackType == TrackType.Other)
                .OrderBy(t => t.MkvToolsTrackNumber)
                .ToList().ForEach(t => trackNumbers.Add(t.MkvToolsTrackNumber));

            StringBuilder mkvMergeTrackOrder = new StringBuilder();
            trackNumbers.ForEach(n => mkvMergeTrackOrder.AppendFormat("0:{0},", n));
            mkvMergeTrackOrder.Remove(mkvMergeTrackOrder.Length - 1, 1);

            return mkvMergeTrackOrder.ToString();
        }
示例#2
0
        private static void ConvertFlacToAac(VideoFileInfo mkvFile)
        {
            foreach (TrackInfo track in mkvFile.Tracks)
            {
                if (track.Codec == flacCodecID)
                {
                    Console.WriteLine("Transcoding FLAC streams {0}(id:{1}) from {2}",
                        track.Name, track.TrackNumber, mkvFile.VideoFile.FullName);
                    FileInfo aacFile = new FileInfo(tempFolder.FullName + Path.DirectorySeparatorChar +
                        mkvFile.VideoFile.Name + '.' + track.MkvToolsTrackNumber + ".mp4");
                    String ffmpegParameters =
                        String.Format(ffMpegBaseParameters, mkvFile.VideoFile.FullName, track.MkvToolsTrackNumber);
                    String neroAacParameters = String.Format(neroAacEncBaseParameters, aacFile.FullName);

                    String fullCommand = pathToFFMpeg + " " + ffmpegParameters +
                        " | " + pathToNeroAacEnc + " " + neroAacParameters;
                        //We pipe the stream from ffmpeg directly into the neroAAC encoder.
                    Console.WriteLine("ffmpeg to neroAAC Command:");
                    Console.WriteLine(fullCommand);

                    Process transcodeProcess = StartExternalProcess("cmd", "/C " + fullCommand);
                    Console.WriteLine(transcodeProcess.StandardError.ReadToEnd());
                    transcodeProcess.WaitForExit(encodeTimeout * 1000);

                    if (transcodeProcess.HasExited)
                    {
                        if (transcodeProcess.ExitCode != 0 || !aacFile.Exists)
                        {
                            Console.WriteLine("Error with transcoding");
                        }
                        else
                        {
                            track.ExternalFileRef = aacFile;
                        }
                    }
                    else
                    {
                        Console.WriteLine("MKV transcode application took longer than {0} seconds.", encodeTimeout);
                        transcodeProcess.Kill();
                    }
                }
            }
        }
        public static VideoFileInfo ParseMKVInfo(String mkvInfoFile)
        {
            FileInfo infoFile = new FileInfo(mkvInfoFile);
            VideoFileInfo videoInfo = new VideoFileInfo();
            using (TextReader reader = infoFile.OpenText())
            {
                String line = reader.ReadLine();
                while (line != trackStart && !String.IsNullOrEmpty(line))
                {
                    if (line.StartsWith(segmentUid))
                        videoInfo.SegmentUID = line.Substring(segmentUid.Length);
                    line = reader.ReadLine();
                }
                if (line != trackStart)
                    throw new Exception("Invalid info file format or MKV without tracks");

                videoInfo.Tracks = ExtractTrackInfo(reader);
            }
            return videoInfo;
        }
示例#4
0
 private static void TranscodeFlac(VideoFileInfo mkvFile, DirectoryInfo targetFolder)
 {
     ConvertFlacToAac(mkvFile);
     RemuxFile(mkvFile, targetFolder);
 }
示例#5
0
        private static void RemuxFile(VideoFileInfo mkvFile, DirectoryInfo targetFolder)
        {
            FileInfo target = new FileInfo(targetFolder.FullName + Path.DirectorySeparatorChar + mkvFile.VideoFile.Name);
            Console.WriteLine("Remuxing {0} to {1}", mkvFile.VideoFile.FullName, target.FullName);
            String mkvMergeParams = PrepareMkvMergeParameters(mkvFile, target);
            Console.WriteLine("MkvMerge Command:");
            Console.WriteLine(pathToMkvMerge + " " + mkvMergeParams);

            Process mkvMergeProcess = StartExternalProcess(pathToMkvMerge, mkvMergeParams);
            Console.WriteLine(mkvMergeProcess.StandardError.ReadToEnd());
            mkvMergeProcess.WaitForExit(mergeTimeout * 1000);

            if (mkvMergeProcess.HasExited)
            {
                target.Refresh();
                if (mkvMergeProcess.ExitCode != 0 || !target.Exists)
                {
                    Console.WriteLine("Error with mkvMerge");
                }
                else
                {
                    foreach (TrackInfo track in mkvFile.Tracks)
                    {
                        if (track.ExternalFileRef != null && track.ExternalFileRef.Exists)
                            track.ExternalFileRef.Delete();
                    }
                }
            }
            else
            {
                Console.WriteLine("MKV merge application took longer than {0} seconds.", mergeTimeout);
                mkvMergeProcess.Kill();
            }
        }
示例#6
0
        private static String PrepareMkvMergeParameters(VideoFileInfo mkvFile, FileInfo target)
        {
            StringBuilder mkvMergeParams = new StringBuilder();
            mkvMergeParams.AppendFormat("-o \"{0}\"", target.FullName);

            if (!String.IsNullOrWhiteSpace(mkvFile.SegmentUID))
                mkvMergeParams.AppendFormat(" --segment-uid \"{0}\"", mkvFile.SegmentUID);  //we keep the same segmentUID as source to preserve external chapter support. (OP/ED's etc)

            List<String> audioIdsToSkip = new List<String>();
            foreach (TrackInfo track in mkvFile.Tracks)
            {
                if (track.TrackType == TrackType.Video)
                {
                    mkvMergeParams.AppendFormat(" --compression {0}:none", track.MkvToolsTrackNumber);
                }
                if (track.TrackType == TrackType.Audio && track.Codec == flacCodecID)
                {
                    audioIdsToSkip.Add(track.MkvToolsTrackNumber.ToString());
                }
            }
            mkvMergeParams.AppendFormat(" --audio-tracks !{0}", String.Join(",", audioIdsToSkip));
            mkvMergeParams.AppendFormat(" \"{0}\"", mkvFile.VideoFile.FullName);

            foreach (TrackInfo track in mkvFile.Tracks)
            {
                if (track.TrackType == TrackType.Audio && track.Codec == flacCodecID)
                {
                    String reworkedTrackName = ReplaceFlacIndicator(track.Name);
                    if(!String.IsNullOrWhiteSpace(reworkedTrackName))
                        mkvMergeParams.AppendFormat(" --track-name \"0:{0}\"", reworkedTrackName);
                    if (String.IsNullOrWhiteSpace(track.Language))  //eng is the default track language, this is sometimes ommited in the source files resulting in an empty language code.
                        mkvMergeParams.AppendFormat(" --language 0:eng");
                    else
                        mkvMergeParams.AppendFormat(" --language 0:{0}", track.Language); ;
                    mkvMergeParams.AppendFormat(" --compression 0:none");
                    if (!track.Default)      //yes is the default value of this flag, there is no need to specify this case.
                        mkvMergeParams.Append(" --default-track 0:no");
                    if(track.Forced)
                        mkvMergeParams.Append(" --forced-track 0:yes");
                    //Ensure we only grab audio from this file
                    mkvMergeParams.Append(" --no-video --no-subtitles --no-buttons --no-track-tags");
                    mkvMergeParams.Append(" --no-chapters --no-attachments --no-global-tags");
                    mkvMergeParams.AppendFormat(" --audio-tracks 0 \"{0}\"", track.ExternalFileRef.FullName);
                }
            }

            List<String> trackOrder = new List<String>();
            Int32 externalFileCounter = 0;
            foreach (TrackInfo track in mkvFile.Tracks)
            {
                if (track.TrackType == TrackType.Audio && track.Codec == flacCodecID)
                {
                    externalFileCounter += 1;
                    trackOrder.Add(String.Format("{0}:0", externalFileCounter));
                }
                else
                {
                    trackOrder.Add(String.Format("0:{0}", track.MkvToolsTrackNumber));
                }
            }
            mkvMergeParams.AppendFormat(" --track-order {0}", String.Join(",", trackOrder));

            return mkvMergeParams.ToString();
        }