public void generate() { try { while (downloader.IsComplete == false) { System.Threading.Thread.Sleep(100); } if (downloader.IsFailed) { this.complete = true; return; } try { int duration = -1; if (downloader.ProbeInfo != null && downloader.ProbeInfo.format != null) { if (downloader.ProbeInfo.format.duration != null) { var dur = double.Parse(downloader.ProbeInfo.format.duration as string); duration = (int)((new TimeSpan(0, 0, (int)dur)).TotalSeconds); } } this.thumbTaskCommand = this.buildThumbnailArguments(this.workingDir, this.downloader.Destination, duration); log.Debug("Executing Thumbnail Task: " + id); StringBuilder results = new StringBuilder(); int exitCode = 0; results.Append(FFmpeg.Exec(this.thumbTaskCommand, out exitCode)); if (results.ToString().Contains("Output file is empty")) { results.Clear(); log.Debug("No thumbnails generated for: " + id + " trying shorter version"); this.thumbTaskCommand = this.buildThumbnailArgumentsShort(this.workingDir, this.downloader.Destination); results.Append(FFmpeg.Exec(this.thumbTaskCommand, out exitCode)); } log.Debug("Finished thumbnail task: " + id); //TranscoderResult result = new TranscoderResult(jobID, results.ToString()); log.Debug("Fetched thumbnail result" + id); //moveThumbs(); // log.Debug("Thumb files moved to remote server: " + id); if (FFRest.config["mode"] == "move") { Directory.CreateDirectory(FFRest.config["file-root"] + Path.DirectorySeparatorChar + FFRest.config["thumb-destination"] + Path.DirectorySeparatorChar + id); for (var x = 1; x <= 5; x++) { if (File.Exists(this.workingDir + "thumbnail-" + id + "_000" + x + ".jpg")) { if (File.Exists(FFRest.config["file-root"] + Path.DirectorySeparatorChar + FFRest.config["thumb-destination"] + Path.DirectorySeparatorChar + id + Path.DirectorySeparatorChar + "thumbnail-" + id + "_000" + x + ".jpg")) { File.Delete(FFRest.config["file-root"] + Path.DirectorySeparatorChar + FFRest.config["thumb-destination"] + Path.DirectorySeparatorChar + id + Path.DirectorySeparatorChar + "thumbnail-" + id + "_000" + x + ".jpg"); } File.Move(this.workingDir + "thumbnail-" + id + "_000" + x + ".jpg", FFRest.config["file-root"] + Path.DirectorySeparatorChar + FFRest.config["thumb-destination"] + Path.DirectorySeparatorChar + id + Path.DirectorySeparatorChar + "thumbnail-" + id + "_000" + x + ".jpg"); } } } } catch (Exception ex) { log.Error("Failed to extract thumbnails", ex); } complete = true; } catch (Exception ex) { log.Error("Exception occured before thumbnail extraction could begin", ex); } }
public object Handle() { try { while (!job.DownloadComplete) { System.Threading.Thread.Sleep(100); } this.startTime = DateTime.Now; this.result.StartTime = this.startTime; if (multiPass) { this.result.Status = "Waiting on First Pass"; while (!job.FirstPasses[this.extension].IsComplete) { System.Threading.Thread.Sleep(100); } if (job.FirstPasses[this.extension].IsFailed) { log.Error("Multipass first pass failed JobID: " + this.job.JobToken + " TaskID: " + this.TaskID); FFRest.stats.CompleteTask(); this.result.FinishTime = DateTime.Now; this.result.Status = "Failed"; this.result.PercentComplete = 0; return(this.result); } } this.result.Status = "Processing"; //Get Video Info log.Debug("Beginning transcoding task processing JobID: " + this.job.JobToken + " TaskID: " + this.taskId); if (job.Download.ProbeInfo == null) { FFRest.stats.CompleteTask(); //return new TranscoderResult(job.JobToken,taskId,this.startTime); this.result.FinishTime = DateTime.Now; this.result.Status = "Failed/Skipped"; this.result.PercentComplete = 0; return(this.result); } if (job.Download.IsFailed) { FFRest.stats.CompleteTask(); //return new TranscoderResult(job.JobToken,taskId,this.startTime); this.result.FinishTime = DateTime.Now; this.result.Status = "Failed/Skipped"; this.result.PercentComplete = 0; return(this.result); } bool can1080 = false; bool can720 = false; string fpsString = ""; int frameRate = 0; foreach (var stream in job.Download.ProbeInfo.streams) { log.Debug(stream.codec_type); log.Debug(stream.width); if (stream.codec_type.ToString() == "video") { int width; fpsString = stream.avg_frame_rate.ToString(); var d = float.Parse(fpsString.Substring(fpsString.IndexOf("/") + 1)); var r = float.Parse(fpsString.Substring(0, fpsString.IndexOf("/"))); frameRate = (int)Math.Round(r / d); if (int.TryParse(stream.width.ToString(), out width)) { if (width >= 1920) { can1080 = true; can720 = true; } if (width >= 1280) { can720 = true; } } } } log.Debug("Format Supports: 1080p" + can1080 + " 720p:" + can720); var doProcessing = true; if ((taskOptions.Contains("hd1080") || taskOptions.Contains("-s 1920x1080") || taskOptions.Contains("-s '1920x1080'") || taskOptions.Contains("-s \"1920x1080\"")) && !can1080) { doProcessing = false; } if ((taskOptions.Contains("hd720") || taskOptions.Contains("-s 1280x720") || taskOptions.Contains("-s '1280x720'") || taskOptions.Contains("-s \"1280x720\"")) && !can720) { doProcessing = false; } if (doProcessing) { string resolution = ""; if (taskOptions.ToLower().Contains("hd720")) { resolution = "1280x720"; } else if (taskOptions.ToLower().Contains("hd1080")) { resolution = "1920x1080"; } else if (taskOptions.ToLower().Contains("hd480")) { resolution = "720x480"; } else if (taskOptions.ToLower().Contains("sd480")) { resolution = "720x480"; } else if (Regex.IsMatch(taskOptions, "-s [\"']?([0-9]+x[0-9]+)[\"']?")) { resolution = Regex.Match(taskOptions, "-s [\"']?([0-9]+x[0-9]+)[\"']?").Groups[1].Value; } string bitrate = ""; if (taskOptions.ToLower().Contains("-minrate")) { bitrate = taskOptions.Substring(taskOptions.IndexOf("-minrate") + 9); bitrate = bitrate.Substring(0, bitrate.IndexOf(" ")); } else if (taskOptions.ToLower().Contains("-maxrate")) { bitrate = taskOptions.Substring(taskOptions.IndexOf("-maxrate") + 9); bitrate = bitrate.Substring(0, bitrate.IndexOf(" ")); } else if (taskOptions.ToLower().Contains("-b:v")) { bitrate = taskOptions.Substring(taskOptions.IndexOf("-b:v") + 5); bitrate = bitrate.Substring(0, bitrate.IndexOf(" ")); } this.taskOptions = this.taskOptions.Replace("'{{bitrate}}'", bitrate); this.taskOptions = this.taskOptions.Replace("'{{fps}}'", frameRate.ToString()); this.taskOptions = this.taskOptions.Replace("'{{fps2x}}'", (frameRate * 2).ToString()); this.taskOptions = this.taskOptions.Replace("'{{resolution}}'", resolution); this.taskOptions = this.taskOptions.Replace("{{bitrate}}", bitrate); this.taskOptions = this.taskOptions.Replace("{{fps}}", frameRate.ToString()); this.taskOptions = this.taskOptions.Replace("{{fps2x}}", (frameRate * 2).ToString()); this.taskOptions = this.taskOptions.Replace("{{resolution}}", resolution); this.taskCommand = this.buildTranscodingArguments(this.workingDir, this.job.Download.Destination, this.taskOptions, this.outputFile); log.Debug("Executing Task:" + this.taskId); StringBuilder results = new StringBuilder(); int exitCode = 0; if (job.Download.ProbeInfo != null && job.Download.ProbeInfo.format != null && job.Download.ProbeInfo.format.duration != null) { var duration = double.Parse(job.Download.ProbeInfo.format.duration as string); StringBuilder buffer = new StringBuilder(); int idx = 0; results.Append(FFmpeg.Exec(this.taskCommand, out exitCode, (x) => { buffer.Append(x); int length = buffer.Length - idx; if (idx >= buffer.Length - 1) { return; } string data = buffer.ToString(idx, length); int rIdx = 0; data = data.Replace("\r\n", "\n"); data = data.Replace("\r", "\n"); int pos = 0; while (rIdx < data.Length && (pos = data.Substring(rIdx).IndexOf("\n")) > -1) { //log.Trace("Result Data: " +x); idx += pos + 1; var line = data.Substring(rIdx, pos + 1).Trim(); rIdx += pos + 1; if (line.StartsWith("frame=")) { line = line.Substring(line.IndexOf("time=") + 5); line = line.Substring(0, line.IndexOf(" ")); var timeSpan = TimeSpan.Parse(line.Trim()); var activePercent = timeSpan.TotalSeconds / duration; activePercent = activePercent * 100; if (activePercent > 100) { activePercent = 100; } if (this.segmentFile != null) { activePercent -= 10; } if (this.result.PercentComplete < (int)activePercent) { this.result.PercentComplete = (int)activePercent; } } } })); } else { results.Append(FFmpeg.Exec(this.taskCommand, out exitCode)); } if (exitCode != 0) { log.Error("Failed to transcode file " + results.ToString()); this.result.FinishTime = DateTime.Now; this.result.Status = "Failed"; this.result.PercentComplete = 0; return(this.result); } List <string> segments = null; if (this.segmentFile != null) { var cmd = this.buildTranscodingSegmentArguments(this.workingDir, this.outputFile, this.taskOptions, this.segmentFile); results.Append(" "); results.Append(FFmpeg.Exec(cmd, out exitCode)); if (File.Exists(this.workingDir + this.segmentFile)) { segments = new List <string>(); string line = null; using (StreamReader sw = new StreamReader(this.workingDir + this.segmentFile)) { while ((line = sw.ReadLine()) != null) { if (line.Trim().EndsWith(".ts")) { segments.Add(line.Trim()); } } } } } log.Debug("Finished transcoding JobID: " + this.job.JobToken + " TaskID: " + taskId); if (this.segmentFile == null) { this.result.FinishTime = DateTime.Now; this.result.Status = "Complete"; this.result.PercentComplete = 100; this.result.ResultVideo = outputFile; } else { this.result.FinishTime = DateTime.Now; this.result.Playlist = this.segmentFile; this.result.Status = "Complete"; this.result.PercentComplete = 100; this.result.Segments = segments; this.result.ResultVideo = outputFile; } FFRest.stats.CompleteTask(); return(this.result); } else { log.Debug("Skipping task JobID: " + this.job.JobToken + " TaskID:" + this.taskId); FFRest.stats.CompleteTask(); this.result.FinishTime = DateTime.Now; this.result.Status = "Skipped"; this.result.PercentComplete = 0; return(this.result); } } catch (Exception e) { log.Error("Exception occured in task run", e); this.result.FinishTime = DateTime.Now; this.result.Status = "Failed"; this.result.PercentComplete = 0; } FFRest.stats.CompleteTask(); return(this.result); }
public void RunPass() { try { // TODO configure this sleep time // Make sure we have a file available while (!job.DownloadComplete) { System.Threading.Thread.Sleep(100); } // If we were not able to probe the file we cannot proceed if (job.Download.ProbeInfo != null) { // Multipass options must be provided if (string.IsNullOrEmpty(multiPassOptions)) { this.complete = true; this.failed = true; log.Debug("No multi pass options provided"); throw new JobFailureException("No multi pass options provided"); } string fpsString; int frameRate = 0; // Get the current frame rate for variable replacement // Todo possible look into other variables that could be replaced in foreach (var stream in job.Download.ProbeInfo.streams) { if (stream.codec_type.ToString() == "video") { fpsString = stream.avg_frame_rate.ToString(); var d = float.Parse(fpsString.Substring(fpsString.IndexOf("/") + 1)); var r = float.Parse(fpsString.Substring(0, fpsString.IndexOf("/"))); frameRate = (int)Math.Round(r / d); } } this.multiPassOptions = this.multiPassOptions.Replace("'{{fps}}'", frameRate.ToString()); this.multiPassOptions = this.multiPassOptions.Replace("'{{fps2x}}'", (frameRate * 2).ToString()); this.multiPassOptions = this.multiPassOptions.Replace("{{fps}}", frameRate.ToString()); this.multiPassOptions = this.multiPassOptions.Replace("{{fps2x}}", (frameRate * 2).ToString()); var args = buildTranscodingArguments(this.workingDir, this.dest, this.multiPassOptions, "fastpass_" + this.dest + "." + this.multiPassExtension); int status = 0; var fastPassData = FFmpeg.Exec(args, out status); if (status != 0) { this.complete = true; this.failed = true; log.Debug("Failed to perform fast pass of data"); throw new JobFailureException("Failed to perform fast pass of data"); } this.complete = true; } else { this.complete = true; this.failed = true; log.Debug("Failed to perform fast pass of data missing probe info"); throw new JobFailureException("Failed to perform fast pass of data missing probe info"); } } catch (Exception ex) { log.Error("An error occured Download()", ex); } }