public static bool CreateVideoThumb(string aVideoPath, string aThumbPath, bool aOmitCredits) { if (!File.Exists(aVideoPath)) { Log.Info("TvThumbnails.VideoThumbCreator: File {0} not found!", aVideoPath); return false; } if (!File.Exists(_extractorPath)) { Log.Info("TvThumbnails.VideoThumbCreator: No {0} found to generate thumbnails of your video!", _extractorPath); return false; } //TODO Blacklist stuff /*bool isCachedThumbBlacklisted = IsCachedThumbBlacklisted(aVideoPath); IVideoThumbBlacklist blacklist = GlobalServiceProvider.Get<IVideoThumbBlacklist>(); if (blacklist != null && blacklist.Contains(aVideoPath)) if (isCachedThumbBlacklisted) { Log.Info("Skipped creating thumbnail for {0}, it has been blacklisted because last attempt failed", aVideoPath); return false; }*/ string ShareThumb = ""; int TimeIntBwThumbs = 0; int preGapSec = Thumbs.TimeOffset * 60; Log.Debug("TvThumbnails.VideoThumbCreator: preGapSec: {0}", preGapSec); MediaInfo = new MediaInfoWrapper.MediaInfoWrapper(aVideoPath); int Duration = MediaInfo.VideoDuration / 1000; if (preGapSec > Duration) { preGapSec = Duration - 240; } if (preGapSec < 0) { preGapSec = 4; } TimeIntBwThumbs = (Duration - preGapSec) / 4; Log.Debug("{0} duration is {1}, TimeIntBwThumbs is {2}", aVideoPath, Duration, TimeIntBwThumbs); bool Success = false; string strFilenamewithoutExtension = Path.ChangeExtension(aVideoPath, null); /* string ffmpegArgs = string.Format("select=isnan(prev_selected_t)+gte(t-prev_selected_t\\,{0}),", TimeIntBwThumbs) + string.Format("yadif=0:-1:0,") + string.Format("scale={0}:{1},", 600, 337) + string.Format("setsar=1:1,") + string.Format("tile={0}x{1}", Thumbs.PreviewColumns, Thumbs.PreviewRows); */ string ffmpegFallbackArgs = string.Format("select=isnan(prev_selected_t)+gte(t-prev_selected_t\\,{0}),", 5) + string.Format("yadif=0:-1:0,") + string.Format("scale={0}:{1},", 600, 337) + string.Format("setsar=1:1,") + string.Format("tile={0}x{1}", Thumbs.PreviewColumns, Thumbs.PreviewRows); /* string ExtractorArgs = string.Format("-loglevel quiet -ss {0} ", preGapSec) + string.Format("-i \"{0}\" ", aVideoPath) + string.Format("-vf {0} ", ffmpegArgs) + string.Format("-vframes 1 -vsync 0 ") + string.Format("-an \"{0}_s.jpg\"", strFilenamewithoutExtension); */ string ExtractorFallbackArgs = string.Format("-loglevel quiet -ss 5 ") + string.Format("-i \"{0}\" ", aVideoPath) + string.Format("-vf {0} ", ffmpegFallbackArgs) + string.Format("-vframes 1 -vsync 0 ") + string.Format("-an \"{0}_s.jpg\"", strFilenamewithoutExtension); try { // Use this for the working dir to be on the safe side string TempPath = Path.GetTempPath(); string OutputThumb = string.Format("{0}{1}", Path.ChangeExtension(aVideoPath, null), ".jpg"); ShareThumb = OutputThumb.Replace(".jpg", ".jpg"); // Use Temp folder string strFilenamewithoutExtensionTemp = Path.GetTempPath() + Path.GetFileName(strFilenamewithoutExtension); string ShareThumbTemp = Path.GetTempPath() + Path.GetFileName(ShareThumb); if ((Thumbs.LeaveShareThumb && !File.Exists(ShareThumb)) // No thumb in share although it should be there || (!Thumbs.LeaveShareThumb && !File.Exists(aThumbPath))) // No thumb cached and no chance to find it in share { List<string> pictureList = new List<string>(); string ffmpegArgs = null; string ExtractorArgs = null; int TimeOffset = 0; int i; for (i = 0; i < (Thumbs.PreviewColumns * Thumbs.PreviewRows); i++) { TimeOffset = preGapSec + i * TimeIntBwThumbs; ffmpegArgs = string.Format("select=isnan(prev_selected_t)+gte(t-prev_selected_t" + "\\" + ",{0}),yadif=0:-1:0,scale=600:337,setsar=1:1,tile={1}x{2}", 1, 1, 1); ExtractorArgs = string.Format("-loglevel quiet -ss {0} -i \"{1}\" -vf {2} -vframes 1 -vsync 0 -an \"{3}_{4}.jpg\"", TimeOffset, aVideoPath, ffmpegArgs, strFilenamewithoutExtensionTemp, i); Success = StartProcess(_extractorPath, ExtractorArgs, TempPath, 120000, true, GetMtnConditions()); Log.Debug("TvThumbnails.VideoThumbCreator: thumb creation {0}", ExtractorArgs); if (!Success) { Log.Debug("TvThumbnails.VideoThumbCreator: failed, try to fallback {0}", strFilenamewithoutExtensionTemp); break; } else { pictureList.Add(string.Format("{0}_{1}.jpg", strFilenamewithoutExtensionTemp, i)); } } // generate thumb if all sub pictures was created if (i == Thumbs.PreviewColumns * Thumbs.PreviewRows) { if (CreateTileThumb(pictureList, string.Format("{0}.jpg", strFilenamewithoutExtensionTemp), Thumbs.PreviewColumns, Thumbs.PreviewRows)) { Log.Debug("TvThumbnails.VideoThumbCreator: thumb creation success {0}", ShareThumbTemp); File.SetAttributes(ShareThumbTemp, File.GetAttributes(ShareThumbTemp) & ~FileAttributes.Hidden); } else { Log.Debug("TvThumbnails.VideoThumbCreator: failed, try to fallback {0}", strFilenamewithoutExtensionTemp); } } else { // Maybe the pre-gap was too large or not enough sharp & light scenes could be caught Log.Debug("TvThumbnails.VideoThumbCreator: 1st trying was not success, 2nd trying in progress with ExtractorFallbackArgs: {0}", ExtractorFallbackArgs); Thread.Sleep(500); Success = StartProcess(_extractorPath, ExtractorFallbackArgs, TempPath, 120000, true, GetMtnConditions()); if (!Success) Log.Info("TvThumbnails.VideoThumbCreator: {0} has not been executed successfully with arguments: {1}", _extractApp, ExtractorFallbackArgs); } // give the system a few IO cycles Thread.Sleep(500); // make sure there's no process hanging KillProcess(Path.ChangeExtension(_extractApp, null)); try { // Move Final Thumbnail from Temp folder to Thumbs folder File.Move(ShareThumbTemp, aThumbPath); File.SetAttributes(aThumbPath, File.GetAttributes(aThumbPath) & ~FileAttributes.Hidden); } catch (FileNotFoundException) { Log.Info("TvThumbnails.VideoThumbCreator: {0} did not extract a thumbnail to: {1}", _extractApp, ShareThumbTemp); } catch (Exception) { try { // Clean up File.Delete(ShareThumb); Thread.Sleep(100); } catch (Exception) { } } if (Thumbs.LeaveShareThumb) { if (File.Exists(aThumbPath)) { try { File.Copy(aThumbPath, ShareThumb); File.SetAttributes(ShareThumb, File.GetAttributes(ShareThumb) & ~FileAttributes.Hidden); } catch (Exception) { Log.Debug("TvThumbnails.VideoThumbCreator: Exception on File.Copy({0}, {1})", ShareThumbTemp, ShareThumb); } } } } else { // We have a thumbnail in share but the cache was wiped out - make sure it is recreated if (Thumbs.LeaveShareThumb && !File.Exists(aThumbPath)) // && !File.Exists(aThumbPath)) Success = true; } Thread.Sleep(30); if (File.Exists(ShareThumbTemp)) { if (Success) { int width = (int)Thumbs.ThumbLargeResolution; CreateThumbnail(ShareThumbTemp, aThumbPath, width, width, 0); //CreateThumbnail(ShareThumb, Utils.ConvertToLargeCoverArt(aThumbPath), // (int)Thumbs.ThumbLargeResolution, (int)Thumbs.ThumbLargeResolution, 0, false); } if (Thumbs.LeaveShareThumb) { if (File.Exists(aThumbPath)) { try { File.Copy(aThumbPath, ShareThumb); File.SetAttributes(ShareThumb, File.GetAttributes(ShareThumb) & ~FileAttributes.Hidden); } catch (Exception) { Log.Debug("TvThumbnails.VideoThumbCreator: Exception on File.Copy({0}, {1})", aThumbPath, ShareThumb); } } } } } catch (Exception ex) { Log.Error("TvThumbnails.VideoThumbCreator: Thumbnail generation failed - {0}!", ex.ToString()); } if (File.Exists(aThumbPath) || File.Exists(ShareThumb)) { return true; } else { //TODO Blacklist stuff //if (blacklist != null) //{ // blacklist.Add(aVideoPath); //} //AddCachedThumbToBlacklist(aVideoPath); return false; } }
public static bool CreateVideoThumb(string aVideoPath, string aThumbPath, bool aOmitCredits) { if (!File.Exists(aVideoPath)) { Log.Info("TvThumbnails.VideoThumbCreator: File {0} not found!", aVideoPath); return(false); } if (!File.Exists(_extractorPath)) { Log.Info("TvThumbnails.VideoThumbCreator: No {0} found to generate thumbnails of your video!", _extractorPath); return(false); } //TODO Blacklist stuff /*bool isCachedThumbBlacklisted = IsCachedThumbBlacklisted(aVideoPath); * IVideoThumbBlacklist blacklist = GlobalServiceProvider.Get<IVideoThumbBlacklist>(); * if (blacklist != null && blacklist.Contains(aVideoPath)) * if (isCachedThumbBlacklisted) * { * Log.Info("Skipped creating thumbnail for {0}, it has been blacklisted because last attempt failed", aVideoPath); * return false; * }*/ string ShareThumb = ""; int TimeIntBwThumbs = 0; int TimeToSeek = 3; int preGapSec = Thumbs.TimeOffset * 60; Log.Debug("TvThumbnails.VideoThumbCreator: preGapSec: {0}", preGapSec); MediaInfo = new MediaInfoWrapper.MediaInfoWrapper(aVideoPath); int Duration = MediaInfo.VideoDuration / 1000; if (Duration == 0) { Log.Debug("TvThumbnails.VideoThumbCreator: the {0} is corrupt.", aVideoPath); return(false); } if (preGapSec > Duration) { preGapSec = (Duration / 100) * 20; // 20% of the duration } TimeIntBwThumbs = (Duration - preGapSec) / ((Thumbs.PreviewColumns * Thumbs.PreviewRows) + 1);; Log.Debug("{0} duration is {1}, TimeIntBwThumbs is {2}", aVideoPath, Duration, TimeIntBwThumbs); bool Success = false; string strFilenamewithoutExtension = Path.ChangeExtension(aVideoPath, null); string ffmpegFallbackArgs = string.Format("yadif=0:-1:0,") + string.Format("scale={0}:{1},", 600, 337) + string.Format("setsar=1:1,") + string.Format("tile={0}x{1}", Thumbs.PreviewColumns, Thumbs.PreviewRows); string ExtractorFallbackArgs = string.Format("-loglevel quiet -ss 5 ") + string.Format("-i \"{0}\" ", aVideoPath) + string.Format("-y -vf {0} ", ffmpegFallbackArgs) + string.Format("-ss {0} ", TimeToSeek) + string.Format("-vframes 1 -vsync 0 ") + string.Format("-an \"{0}_s.jpg\"", strFilenamewithoutExtension); try { // Use this for the working dir to be on the safe side string TempPath = Path.GetTempPath(); string OutputThumb = string.Format("{0}{1}", Path.ChangeExtension(aVideoPath, null), ".jpg"); ShareThumb = OutputThumb.Replace(".jpg", ".jpg"); // Use Temp folder string strFilenamewithoutExtensionTemp = Path.GetTempPath() + Path.GetFileName(strFilenamewithoutExtension); string ShareThumbTemp = Path.GetTempPath() + Path.GetFileName(ShareThumb); if ((Thumbs.LeaveShareThumb && !File.Exists(ShareThumb)) || // No thumb in share although it should be there (!Thumbs.LeaveShareThumb && !File.Exists(aThumbPath))) // No thumb cached and no chance to find it in share { List <string> pictureList = new List <string>(); string ffmpegArgs = null; string ExtractorArgs = null; int TimeOffset = 0; int i; for (i = 0; i < (Thumbs.PreviewColumns * Thumbs.PreviewRows); i++) { TimeOffset = preGapSec + i * TimeIntBwThumbs; ffmpegArgs = string.Format("yadif=0:-1:0,scale=600:337,setsar=1:1,tile={0}x{1}", 1, 1); ExtractorArgs = string.Format("-loglevel quiet -ss {0} -i \"{1}\" -y -ss {2} -vf {3} -vframes 1 -vsync 0 -an \"{4}_{5}.jpg\"", TimeOffset, aVideoPath, TimeToSeek, ffmpegArgs, strFilenamewithoutExtensionTemp, i); Success = StartProcess(_extractorPath, ExtractorArgs, TempPath, 120000, true, GetMtnConditions()); Log.Debug("TvThumbnails.VideoThumbCreator: thumb creation {0}", ExtractorArgs); if (!Success) { Log.Debug("TvThumbnails.VideoThumbCreator: failed, try to fallback {0}", strFilenamewithoutExtensionTemp); break; } else { pictureList.Add(string.Format("{0}_{1}.jpg", strFilenamewithoutExtensionTemp, i)); } } // generate thumb if all sub pictures was created if (i == Thumbs.PreviewColumns * Thumbs.PreviewRows) { if (CreateTileThumb(pictureList, string.Format("{0}.jpg", strFilenamewithoutExtensionTemp), Thumbs.PreviewColumns, Thumbs.PreviewRows)) { Log.Debug("TvThumbnails.VideoThumbCreator: thumb creation success {0}", ShareThumbTemp); File.SetAttributes(ShareThumbTemp, File.GetAttributes(ShareThumbTemp) & ~FileAttributes.Hidden); } else { Log.Debug("TvThumbnails.VideoThumbCreator: failed, try to fallback {0}", strFilenamewithoutExtensionTemp); } } else { // Maybe the pre-gap was too large or not enough sharp & light scenes could be caught Log.Debug("TvThumbnails.VideoThumbCreator: 1st trying was not success, 2nd trying in progress with ExtractorFallbackArgs: {0}", ExtractorFallbackArgs); Thread.Sleep(500); Success = StartProcess(_extractorPath, ExtractorFallbackArgs, TempPath, 120000, true, GetMtnConditions()); if (!Success) { Log.Info("TvThumbnails.VideoThumbCreator: {0} has not been executed successfully with arguments: {1}", _extractApp, ExtractorFallbackArgs); } } // give the system a few IO cycles Thread.Sleep(500); // make sure there's no process hanging KillProcess(Path.ChangeExtension(_extractApp, null)); try { // Move Final Thumbnail from Temp folder to Thumbs folder File.Move(ShareThumbTemp, aThumbPath); File.SetAttributes(aThumbPath, File.GetAttributes(aThumbPath) & ~FileAttributes.Hidden); } catch (FileNotFoundException) { Log.Info("TvThumbnails.VideoThumbCreator: {0} did not extract a thumbnail to: {1}", _extractApp, ShareThumbTemp); } catch (Exception) { try { // Clean up File.Delete(ShareThumb); Thread.Sleep(100); } catch (Exception) { } } if (Thumbs.LeaveShareThumb) { if (File.Exists(aThumbPath)) { try { File.Copy(aThumbPath, ShareThumb); File.SetAttributes(ShareThumb, File.GetAttributes(ShareThumb) & ~FileAttributes.Hidden); } catch (Exception) { Log.Debug("TvThumbnails.VideoThumbCreator: Exception on File.Copy({0}, {1})", ShareThumbTemp, ShareThumb); } } } } else { // We have a thumbnail in share but the cache was wiped out - make sure it is recreated if (Thumbs.LeaveShareThumb && !File.Exists(aThumbPath)) // && !File.Exists(aThumbPath)) { Success = true; } } Thread.Sleep(30); if (File.Exists(ShareThumbTemp)) { if (Success) { int width = (int)Thumbs.ThumbLargeResolution; CreateThumbnail(ShareThumbTemp, aThumbPath, width, width, 0); //CreateThumbnail(ShareThumb, Utils.ConvertToLargeCoverArt(aThumbPath), // (int)Thumbs.ThumbLargeResolution, (int)Thumbs.ThumbLargeResolution, 0, false); } if (Thumbs.LeaveShareThumb) { if (File.Exists(aThumbPath)) { try { File.Copy(aThumbPath, ShareThumb); File.SetAttributes(ShareThumb, File.GetAttributes(ShareThumb) & ~FileAttributes.Hidden); } catch (Exception) { Log.Debug("TvThumbnails.VideoThumbCreator: Exception on File.Copy({0}, {1})", aThumbPath, ShareThumb); } } } } } catch (Exception ex) { Log.Error("TvThumbnails.VideoThumbCreator: Thumbnail generation failed - {0}!", ex.ToString()); } if (File.Exists(aThumbPath) || File.Exists(ShareThumb)) { return(true); } else { //TODO Blacklist stuff //if (blacklist != null) //{ // blacklist.Add(aVideoPath); //} //AddCachedThumbToBlacklist(aVideoPath); return(false); } }