public override async Task <ResultType> Run(CancellationToken cancellationToken)
        {
            JobStatus = VideoJobStatus.Running;
            Status    = "Checking files...";

            if (cancellationToken.IsCancellationRequested)
            {
                return(ResultType.Cancelled);
            }

            string file = VideoInfo.VideoId;
            string path = Path.GetDirectoryName(file);
            string name = Path.GetFileNameWithoutExtension(file);

            List <string> ffmpegOptions;
            string        postfixOld;
            string        postfixNew;
            string        outputformat;

            if (VideoInfo is FFMpegReencodeJobVideoInfo)
            {
                FFMpegReencodeJobVideoInfo ffvi = VideoInfo as FFMpegReencodeJobVideoInfo;
                ffmpegOptions = ffvi.FFMpegOptions;
                postfixOld    = ffvi.PostfixOld;
                postfixNew    = ffvi.PostfixNew;
                outputformat  = ffvi.OutputFormat;
            }
            else
            {
                ffmpegOptions = new List <string>()
                {
                    "-c:v", "libx264",
                    "-preset", "slower",
                    "-crf", "23",
                    "-g", "2000",
                    "-c:a", "copy",
                    "-max_muxing_queue_size", "100000",
                };
                postfixOld   = "_chunked";
                postfixNew   = "_x264crf23";
                outputformat = "mp4";
            }
            string ext = "." + outputformat;

            string chunked          = postfixOld;
            string postfix          = postfixNew;
            string newfile          = Path.Combine(path, postfix, name.Substring(0, name.Length - chunked.Length) + postfix + ext);
            string newfileinlocal   = Path.Combine(path, name.Substring(0, name.Length - chunked.Length) + postfix + ext);
            string tempfile         = Path.Combine(path, name.Substring(0, name.Length - chunked.Length) + postfix + "_TEMP" + ext);
            string chunkeddir       = Path.Combine(path, chunked);
            string postfixdir       = Path.Combine(path, postfix);
            string oldfileinchunked = Path.Combine(chunkeddir, Path.GetFileName(file));

            FFProbeResult probe       = null;
            string        encodeinput = null;

            if (await Util.FileExists(file))
            {
                probe = await FFMpegUtil.Probe(file);

                encodeinput = file;
            }
            else if (await Util.FileExists(oldfileinchunked))
            {
                probe = await FFMpegUtil.Probe(oldfileinchunked);

                encodeinput = oldfileinchunked;
            }

            if (probe != null)
            {
                VideoInfo = new FFMpegReencodeJobVideoInfo(file, probe, ffmpegOptions, postfixOld, postfixNew, outputformat);
            }

            // if the input file doesn't exist we might still be in a state where we can set this to finished if the output file already exists, so continue anyway

            bool newfileexists = await Util.FileExists(newfile);

            bool newfilelocalexists = await Util.FileExists(newfileinlocal);

            if (!newfileexists && !newfilelocalexists)
            {
                if (encodeinput == null)
                {
                    // neither input nor output exist, bail
                    Status = "Missing!";
                    return(ResultType.Failure);
                }

                if (await Util.FileExists(tempfile))
                {
                    await Util.DeleteFile(tempfile);
                }

                if (cancellationToken.IsCancellationRequested)
                {
                    return(ResultType.Cancelled);
                }

                Status = "Encoding " + newfile + "...";
                await StallWrite(newfile, new FileInfo( encodeinput ).Length, cancellationToken);

                if (cancellationToken.IsCancellationRequested)
                {
                    return(ResultType.Cancelled);
                }
                Directory.CreateDirectory(postfixdir);
                FFMpegReencodeJobVideoInfo ffmpegVideoInfo = VideoInfo as FFMpegReencodeJobVideoInfo;
                await Reencode(newfile, encodeinput, tempfile, ffmpegVideoInfo.FFMpegOptions);
            }

            if (!newfileexists && newfilelocalexists)
            {
                Directory.CreateDirectory(postfixdir);
                File.Move(newfileinlocal, newfile);
            }

            if (await Util.FileExists(file) && !await Util.FileExists(oldfileinchunked))
            {
                Directory.CreateDirectory(chunkeddir);
                File.Move(file, oldfileinchunked);
            }

            Status    = "Done!";
            JobStatus = VideoJobStatus.Finished;
            return(ResultType.Success);
        }
예제 #2
0
        public async static Task <List <IVideoInfo> > FetchReencodeableFiles(string path, string additionalOptions)
        {
            string chunked = "_chunked";
            string postfix = "_x264crf23";

            List <string> reencodeFiles = new List <string>();

            foreach (string file in System.IO.Directory.EnumerateFiles(path))
            {
                string name = System.IO.Path.GetFileNameWithoutExtension(file);
                string ext  = Path.GetExtension(file);

                if (ext == ".mp4" && name.EndsWith(chunked))
                {
                    string newfile = Path.Combine(path, postfix, name.Substring(0, name.Length - chunked.Length) + postfix + ext);
                    if (!File.Exists(newfile))
                    {
                        reencodeFiles.Add(System.IO.Path.GetFullPath(file));
                    }
                }
            }

            List <IVideoInfo> rv = new List <IVideoInfo>();

            foreach (string f in reencodeFiles)
            {
                FFProbeResult probe = await FFMpegUtil.Probe(f);

                int framerate;
                try {
                    framerate = (int)Math.Round(probe.Streams.Where(x => x.Framerate > 0.0f).FirstOrDefault().Framerate);
                } catch (Exception) {
                    framerate = 30;
                }
                if (framerate <= 0)
                {
                    framerate = 30;
                }

                // super hacky... probably should improve this stuff
                List <string> ffmpegOptions;
                string        postfixOld;
                string        postfixNew;
                string        outputformat;
                if (additionalOptions == "rescale720_30fps")
                {
                    ffmpegOptions = new List <string>()
                    {
                        "-c:v", "libx264", "-preset", "slower", "-crf", "23",
                        "-g", "300",
                        "-x264-params", "\"min-keyint=30:b-adapt=2\"",
                        "-sws_flags", "lanczos", "-vf", "\"scale=-2:720\"", "-c:a", "copy", "-max_muxing_queue_size", "100000", "-r", "30"
                    };
                    postfixOld   = "_chunked";
                    postfixNew   = "_x264crf23scaled720p30";
                    outputformat = "mkv";
                }
                else if (additionalOptions == "rescale480_30fps")
                {
                    ffmpegOptions = new List <string>()
                    {
                        "-c:v", "libx264", "-preset", "slower", "-crf", "23",
                        "-g", "300",
                        "-x264-params", "\"min-keyint=30:b-adapt=2\"",
                        "-sws_flags", "lanczos", "-vf", "\"scale=-2:480\"", "-c:a", "copy", "-max_muxing_queue_size", "100000", "-r", "30"
                    };
                    postfixOld   = "_chunked";
                    postfixNew   = "_x264crf23scaled480p30";
                    outputformat = "mkv";
                }
                else if (additionalOptions == "30fps")
                {
                    ffmpegOptions = new List <string>()
                    {
                        "-c:v", "libx264", "-preset", "slower", "-crf", "23",
                        "-g", "300",
                        "-x264-params", "\"min-keyint=30:b-adapt=2\"",
                        "-c:a", "copy", "-max_muxing_queue_size", "100000", "-r", "30"
                    };
                    postfixOld   = "_chunked";
                    postfixNew   = "_x264crf23-30";
                    outputformat = "mkv";
                }
                else if (additionalOptions == "rescale720")
                {
                    ffmpegOptions = new List <string>()
                    {
                        "-c:v", "libx264", "-preset", "slower", "-crf", "23",
                        "-g", (framerate * 10).ToString(),
                        "-x264-params", "\"min-keyint=" + framerate.ToString() + ":b-adapt=2\"",
                        "-sws_flags", "lanczos", "-vf", "\"scale=-2:720\"", "-c:a", "copy", "-max_muxing_queue_size", "100000"
                    };
                    postfixOld   = "_chunked";
                    postfixNew   = "_x264crf23scaled720p";
                    outputformat = "mp4";
                }
                else if (additionalOptions == "rescale480")
                {
                    ffmpegOptions = new List <string>()
                    {
                        "-c:v", "libx264", "-preset", "slower", "-crf", "23",
                        "-g", (framerate * 10).ToString(),
                        "-x264-params", "\"min-keyint=" + framerate.ToString() + ":b-adapt=2\"",
                        "-sws_flags", "lanczos", "-vf", "\"scale=-2:480\"", "-c:a", "copy", "-max_muxing_queue_size", "100000"
                    };
                    postfixOld   = "_chunked";
                    postfixNew   = "_x264crf23scaled480p";
                    outputformat = "mp4";
                }
                else
                {
                    ffmpegOptions = new List <string>()
                    {
                        "-c:v", "libx264", "-preset", "slower", "-crf", "23",
                        "-g", (framerate * 10).ToString(),
                        "-x264-params", "\"min-keyint=" + framerate.ToString() + ":b-adapt=2\"",
                        "-c:a", "copy", "-max_muxing_queue_size", "100000"
                    };
                    postfixOld   = "_chunked";
                    postfixNew   = "_x264crf23";
                    outputformat = "mp4";
                }

                IVideoInfo retval = new FFMpegReencodeJobVideoInfo(f, probe, ffmpegOptions, postfixOld, postfixNew, outputformat);

                rv.Add(retval);
            }
            return(rv);
        }