Ejemplo n.º 1
0
            private static Definition ExtractDefinition(FileInfoBase file)
            {
                var streams = new MediaStreamsExtractor(file).Extract();
                var videoStream = streams.Where(stream => stream is MediaStreamsExtractor.IVideoStream).Select(stream => ((MediaStreamsExtractor.IVideoStream) stream).Height).OrderByDescending(h => h);
                if(!videoStream .Any())
                {
                    return Definition.Unknown;
                }

                var height = videoStream.First();
                if(height >= 1080)
                {
                    return Definition.HD1080;
                }
                else if(height >= 720)
                {
                    return Definition.HD720;
                }
                return Definition.SD;
            }
        public bool Extract()
        {
            // Extract metadata.
            var arguments = string.Format ("-source \"{0}\" -listmetadata", File.FullName);
            var output = External.Run (External.Application.SublerCLI, arguments, Console.Out, Console.Error);

            // Map raw metadata into dictionary.
            var mappings = new Dictionary<string, string> ();
            foreach (var line in output.StdOut.Split('\n'))
            {
                var parts = line.Split (':');
                if(parts.Count() > 1)
                {
                    mappings.Add (parts [0].Trim (), parts [1].Trim ());
                }
            }

            // Check if atleast minimum requirements met.
            int tempInt;
            if (string.IsNullOrEmpty (TryRetrieveData(mappings, "TV Show")) || !int.TryParse (TryRetrieveData(mappings, "TV Episode #"), out tempInt))
            {
                return false;
            }

            // Set values.
            TVShowName = TryRetrieveData(mappings, "TV Show");
            int tempSeasonNumber;
            if (int.TryParse (TryRetrieveData(mappings, "TV Season"), out tempSeasonNumber))
            {
                SeasonNumber = tempSeasonNumber;
            }
            EpisodeNumber = int.Parse (mappings ["TV Episode #"]);
            Name = TryRetrieveData(mappings, "Name");
            Description = TryRetrieveData(mappings, "Long Description");
            Genres = TryRetrieveData(mappings, "Genre").Split (',').Select (genre => genre.Trim ()).ToList ();
            Cast = TryRetrieveData(mappings, "Cast").Split (',').Select (cast => cast.Trim ()).ToList ();
            Directors = TryRetrieveData(mappings, "Director").Split (',').Select (director => director.Trim ()).ToList ();
            Screenwriters = TryRetrieveData(mappings, "Screenwriters").Split (',').Select (screenwriter => screenwriter.Trim ()).ToList ();
            DateTime tempReleaseDate;
            if (DateTime.TryParseExact (mappings ["Release Date"], "yyyy-MM-dd", null, DateTimeStyles.None, out tempReleaseDate))
            {
                ReleaseDate = tempReleaseDate;
            }
            Network = TryRetrieveData(mappings, "TV Network");

            // Extract artwork.
            var artworkStream = new MediaStreamsExtractor (File).Extract ().LastOrDefault (stream => stream.Codec == MediaStreamsExtractor.CodecType.PNG
                                                                                           || stream.Codec == MediaStreamsExtractor.CodecType.JPEG);
            if (artworkStream != null)
            {
                var tempfile = _fileSystem.FileInfo.FromFileName (_fileSystem.Path.GetTempFileName () + ".png");
                var ffmepgArguments = string.Format ("-i \"{0}\" -map 0:{1} \"{2}\"", File.FullName, artworkStream.Id, tempfile.FullName);
                if (External.Run (External.Application.FFmpeg, ffmepgArguments, Console.Out, Console.Error).ExitCode == 0)
                {
                    Artwork = tempfile.ToBase64Image ();
                }
                tempfile.Delete ();
            }

            // Return true.
            return true;
        }
Ejemplo n.º 3
0
            public MetadataUpdaterTVShow(MetadataUpdaterTVShowUpdateRequest request)
            {
                File = request.Path.FromSiteFilePath();
                Definition = MediaPod.Interfaces.Models.Definition.Unknown;
                TVShowName = request.TVShowName;
                SeasonNumber = Convert.ToInt32(request.SeasonNumber);
                EpisodeNumber = Convert.ToInt32(request.EpisodeNumber);
                Name = request.Name;
                Description = request.Description;
                Genres = request.Genres.Split(',').Select(genre => genre.Trim()).ToList();
                Cast = request.Cast.Split(',').Select(cast => cast.Trim()).ToList();
                Directors = request.Directors.Split(',').Select(director => director.Trim()).ToList();
                Screenwriters = request.Screenwriters.Split(',').Select(screenwriters => screenwriters.Trim()).ToList();
                ReleaseDate = DateTime.ParseExact(request.ReleaseDate, "yyyy-MM-dd", CultureInfo.InvariantCulture);
                Network = request.Network;
                Artwork = request.Artwork.FromWebImage();

                // Determine definition.
                var streams = new MediaStreamsExtractor(File).Extract();
                var height = streams.Where(stream => stream is MediaStreamsExtractor.IVideoStream).Select(stream => ((MediaStreamsExtractor.IVideoStream) stream).Height).OrderByDescending(h => h).First();
                if(height >= 1080)
                {
                    Definition = Definition.HD1080;
                }
                else if(height >= 720)
                {
                    Definition = Definition.HD720;
                }
                else
                {
                    Definition = Definition.SD;
                }
            }
Ejemplo n.º 4
0
        public Remux(IFileSystem fileSystem, FileInfoBase inputFile, FileInfoBase outputFile, TextWriter stdOut=null, TextWriter stdErr=null)
            : base("Remux" + idCounter++, stdOut, stdErr)
        {
            _action = () =>
            {
                // Create and set working area.
                var workingArea = fileSystem.DirectoryInfo.FromDirectoryName (fileSystem.Path.Combine (fileSystem.Path.Combine (fileSystem.Path.GetTempPath (), Assembly.GetExecutingAssembly().GetName().Name), this.GetType().Name));
                if (!workingArea.Exists)
                {
                    LogOutput("Creating working area at {0}.", workingArea.FullName);
                    workingArea.Create();
                }

                // Get streams and split.
                var streams = new MediaStreamsExtractor(inputFile).Extract().OrderBy(steam => steam.Id);
                var videoStreams = streams.Where(stream => stream is MediaStreamsExtractor.IVideoStream).Select(stream => (MediaStreamsExtractor.IVideoStream) stream).ToList();
                var audioStreams = streams.Where(stream => stream is MediaStreamsExtractor.IAudioStream).Select(stream => (MediaStreamsExtractor.IAudioStream) stream).ToList();
                var subtitleStreams = streams.Where(stream => stream is MediaStreamsExtractor.ISubtitleStream).Select(stream => (MediaStreamsExtractor.ISubtitleStream) stream).ToList();

                // Make working area file.
                var name = outputFile.Name.Replace(outputFile.Extension, "");
                var name1 = name + ".stage1";
                if(string.Compare(outputFile.Extension, ".m4v", System.StringComparison.OrdinalIgnoreCase)==0)
                {
                    name1 += ".mp4";
                }
                else
                {
                    name1 += outputFile.Extension;
                }
                var name2 = name + ".stage2" + outputFile.Extension;
                var workingAreaStage1File = fileSystem.FileInfo.FromFileName(fileSystem.Path.Combine(workingArea.FullName, name1));
                var workingAreaStage2File = fileSystem.FileInfo.FromFileName(fileSystem.Path.Combine(workingArea.FullName, name2));

                // Working variables.
                var maps = new StringBuilder();
                var codecs = new StringBuilder();
                var outputStreamIndex = 0;

                // Copy video streams.
                var h264 = videoStreams.Where(stream => stream.Codec == MediaStreamsExtractor.CodecType.H264).ToList();
                if(h264.Any())
                {
                    h264.Where(stream => stream.Codec == MediaStreamsExtractor.CodecType.H264).ToList().ForEach(stream => MakeCopyStream(stream, maps, codecs, outputStreamIndex++));
                }
                else
                {
                    LogError("Unable to find h264 stream. Will not remux.");
                    return;
                }

                // Copy or transcode aac 2 channel audio streams.
                var acc2Channel = audioStreams.Where(stream => stream.Codec == MediaStreamsExtractor.CodecType.AAC && stream.Channels == 2).ToList();
                if(acc2Channel.Any())
                {
                    acc2Channel.ForEach(stream => MakeCopyStream(stream, maps, codecs, outputStreamIndex++));
                }
                else
                {
                    // Transcode aac 2 channel audio stream from all available audio streams.
                    audioStreams.ForEach(stream =>
                    {
                        maps.AppendFormat(" -map 0:{0} ", stream.Id);
                        codecs.AppendFormat(" -c:{0} aac -ac:a 2 ", outputStreamIndex++);
                    });
                }

                // Copy or transcode higher quality audio stream if possible.
                var ac36Channel = audioStreams.Where(stream => stream.Codec == MediaStreamsExtractor.CodecType.AC3 && stream.Channels == 6).ToList();
                var dts = audioStreams.Where(stream => stream.Codec == MediaStreamsExtractor.CodecType.DTS).ToList();

                // Copy ac3 6 channel streams if exists.
                if(ac36Channel.Any())
                {
                    ac36Channel.ForEach(stream => MakeCopyStream(stream, maps, codecs, outputStreamIndex++));
                }
                else if(dts.Any())
                {
                    // Transcode ac3 6 channel audio streams from dts streams.
                    dts.ForEach(stream =>
                    {
                        maps.AppendFormat(" -map 0:{0} ", stream.Id);
                        codecs.AppendFormat(" -c:{0} ac3 -ac:a 6 ", outputStreamIndex++);
                    });
                }

                // Copy dts streams if exists.
                dts.ForEach(stream => MakeCopyStream(stream, maps, codecs, outputStreamIndex++));

                // Transcode in subtitles if exists.
                subtitleStreams.ForEach(stream =>
                {
                    maps.AppendFormat(" -map 0:{0} ", stream.Id);
                    codecs.AppendFormat(" -c:{0} mov_text ", outputStreamIndex++);
                });

                // Mov atom detils.
                var movFlags = "";
                if(string.Compare(outputFile.Extension, ".m4v", System.StringComparison.OrdinalIgnoreCase)==0
                   || string.Compare(outputFile.Extension, ".mp4", System.StringComparison.OrdinalIgnoreCase)==0)
                {
                    movFlags = " -movflags faststart ";
                }

                // Remux.
                var remuxArguments = string.Format("-i \"{0}\" -y -strict experimental {1} {2} {3} \"{4}\"", inputFile.FullName, maps, codecs, movFlags, workingAreaStage1File.FullName);
                LogOutput("Running FFmpeg with arguments {0}", remuxArguments);
                External.Run(External.Application.FFmpeg, remuxArguments, StdOut, StdErr);

                // Optimise tracks.
                var sublerArguments = string.Format ("-source \"{0}\" -dest \"{1}\" -optimize -itunesfriendly", workingAreaStage1File.FullName, workingAreaStage2File.FullName);
                LogOutput("Running Subler to optimize track with arguments {0}", sublerArguments);
                External.Run(External.Application.SublerCLI, sublerArguments, StdOut, StdErr);

                // Delete stage1 file.
                LogOutput("Deleting workingAreaFile1 {0}", workingAreaStage1File.FullName);
                workingAreaStage1File.Delete();

                // Delete output file if it already exists.
                if(outputFile.Exists)
                {
                    LogOutput("Output file {0} already exists. Will delete.", outputFile.FullName);
                    outputFile.Delete();
                }

                // Move stage 2 file to output file location.
                LogOutput("Moving newly created remux file {0} to output file location {1}.", workingAreaStage2File.FullName, outputFile.FullName);
                workingAreaStage2File.MoveTo(outputFile.FullName);
            };
        }
Ejemplo n.º 5
0
 private static void MakeCopyStream(MediaStreamsExtractor.IStream stream, StringBuilder maps, StringBuilder codecs, int outputStreamIndex)
 {
     maps.AppendFormat(" -map 0:{0} ", stream.Id);
     codecs.AppendFormat(" -c:{0} copy ", outputStreamIndex);
 }