private List <MoveFileItem> LoadListInternal(Guid?videoId) { Entities context = new Entities(); var Result = (from v in context.Media where v.FileName != null && (videoId == null || v.MediaId == videoId) select new MoveFileItem() { VideoId = v.MediaId, MediaType = (MediaType)v.MediaTypeId, Artist = v.Artist, Title = v.Title, MediaCategoryId = v.MediaCategoryId, FileName = v.FileName }).ToList(); DefaultMediaPath PathCalc = new DefaultMediaPath(); PathCalc.LoadData(); foreach (MoveFileItem item in Result) { item.NewFileName = PathCalc.GetDefaultFileName(item.Artist, item.Title, item.MediaCategoryId, item.MediaType) + Path.GetExtension(item.FileName); item.FileExists = File.Exists(Settings.NaturalGroundingFolder + item.FileName); } Result.RemoveAll(v => v.NewFileName == v.FileName || !v.FileExists); return(Result); }
protected override void OnCompleted(object sender, DownloadCompletedEventArgs e) { DownloadItemData IData = e.DownloadInfo.Data as DownloadItemData; Media Video = IData.Media; string Destination = e.DownloadInfo.Destination; string DestinationExt = Path.GetExtension(Destination); Destination = Destination.Substring(0, Destination.Length - Path.GetExtension(Destination).Length); // Ensure download and merge succeeded. if (!FileHasContent(e.DownloadInfo.Destination)) { e.DownloadInfo.Status = DownloadStatus.Failed; return; } // Get final file name. DefaultMediaPath PathCalc = new DefaultMediaPath(); string NewFileName = PathCalc.GetDefaultFileName(Video.Artist, Video.Title, Video.MediaCategoryId, (MediaType)Video.MediaTypeId); Directory.CreateDirectory(Path.GetDirectoryName(Settings.NaturalGroundingFolder + NewFileName)); Video.FileName = NewFileName + DestinationExt; // Move file and overwrite. string DstFile = Settings.NaturalGroundingFolder + Video.FileName; if (File.Exists(DstFile)) { FileOperationAPIWrapper.MoveToRecycleBin(DstFile); } File.Move(Destination + DestinationExt, DstFile); // Add to database EditVideoBusiness Business = new EditVideoBusiness(); Media ExistingData = Business.GetVideoById(Video.MediaId); if (ExistingData != null) { // Edit video info. ExistingData.FileName = Video.FileName; ExistingData.Length = null; ExistingData.Height = null; Business.Save(); } else { // Add new video info. Business.AddVideo(Video); Business.Save(); } base.OnCompleted(sender, e); }
/// <summary> /// Downloads specified video. /// </summary> /// <param name="video">The video to download.</param> /// <param name="queuePos">The position in the queue to auto-play, or -1.</param> /// <param name="upgradeAudio">If true, only the audio will be downloaded and it will be merged with the local video file.</param> /// <param name="callback">The method to call once download is completed.</param> public async Task DownloadVideoAsync(Media video, int queuePos, EventHandler <DownloadCompletedEventArgs> callback, DownloadAction action, DownloadOptions options) { if (video == null || string.IsNullOrEmpty(video.DownloadUrl)) { throw new ArgumentException("Video object is null or doesn't contain a valid YouTube URL."); } // Store in the Temp folder. DefaultMediaPath PathCalc = new DefaultMediaPath(PathManager.TempFilesPath.Substring(Settings.NaturalGroundingFolder.Length)); string Destination = Settings.NaturalGroundingFolder + PathCalc.GetDefaultFileName(video.Artist, video.Title, null, (MediaType)video.MediaTypeId); string DownloadDesc = Path.GetFileName(Destination); Directory.CreateDirectory(PathManager.TempFilesPath); await DownloadVideoAsync(video.DownloadUrl, Destination, DownloadDesc, callback, action, options ?? Options, new DownloadItemData(video, queuePos)).ConfigureAwait(false); }
/// <summary> /// Downloads specified video from YouTube. /// </summary> /// <param name="video">The video to download.</param> /// <param name="queuePos">The position in the queue to auto-play, or -1.</param> /// <param name="upgradeAudio">If true, only the audio will be downloaded and it will be merged with the local video file.</param> /// <param name="callback">The method to call once download is completed.</param> public async Task DownloadVideoAsync(Media video, int queuePos, bool upgradeAudio, EventHandler<DownloadCompletedEventArgs> callback) { if (video == null || string.IsNullOrEmpty(video.DownloadUrl)) throw new ArgumentException("Video object is null or doesn't contain a valid YouTube URL."); if (IsDownloadDuplicate(video)) return; // Store in the Temp folder. DefaultMediaPath PathCalc = new DefaultMediaPath(Settings.TempFilesPath.Substring(Settings.NaturalGroundingFolder.Length)); string Destination = Settings.NaturalGroundingFolder + PathCalc.GetDefaultFileName(video.Artist, video.Title, null, (MediaType)video.MediaTypeId); string DownloadDesc = Path.GetFileName(Destination); Directory.CreateDirectory(Settings.TempFilesPath); // Add DownloadItem right away before doing any async work. DownloadItem DownloadInfo = new DownloadItem(video, Destination, DownloadDesc, queuePos, upgradeAudio, callback); Application.Current.Dispatcher.Invoke(() => downloadsList.Insert(0, DownloadInfo)); // Notify UI of new download to show window. if (DownloadAdded != null) DownloadAdded(this, new EventArgs()); if (downloadsList.Where(d => d.Status == DownloadStatus.Downloading || d.Status == DownloadStatus.Initializing).Count() < Settings.SimultaneousDownloads) await StartDownloadAsync(DownloadInfo).ConfigureAwait(false); }
private List<MoveFileItem> LoadListInternal(Guid? videoId) { Entities context = new Entities(); var Result = (from v in context.Media where v.FileName != null && (videoId == null || v.MediaId == videoId) select new MoveFileItem() { VideoId = v.MediaId, MediaType = (MediaType)v.MediaTypeId, Artist = v.Artist, Title = v.Title, MediaCategoryId = v.MediaCategoryId, FileName = v.FileName }).ToList(); DefaultMediaPath PathCalc = new DefaultMediaPath(); PathCalc.LoadData(); foreach (MoveFileItem item in Result) { item.NewFileName = PathCalc.GetDefaultFileName(item.Artist, item.Title, item.MediaCategoryId, item.MediaType) + Path.GetExtension(item.FileName); item.FileExists = File.Exists(Settings.NaturalGroundingFolder + item.FileName); } Result.RemoveAll(v => v.NewFileName == v.FileName || !v.FileExists); return Result; }
/// <summary> /// Loops through the Media table to set the FileName, Length, Width and Height fields. /// </summary> /// <param name="progress">Reports the progress of the operation. First report is the amount of files to process, then subsequent reports represent the quantity done.</param> /// <returns>Whether some data was modified.</returns> public async Task<bool> LoadMediaInfoAsync(IProgress<int> progress) { // Calling this method when it is already running allows listening to the progress. if (progress != null) { loadingMediaInfoProgress = progress; // First progress report is total count. if (isLoadingMediaInfo) loadingMediaInfoProgress.Report(loadingMediaInfoCount); } if (isLoadingMediaInfo) return false; isLoadingMediaInfo = true; bool HasChanges = false; using (Entities context = new Entities()) { // Loop through all media items with missing Length, Width or Height. var Query = (from v in context.Media where v.FileName == null || v.Length == null || ((v.MediaTypeId == (int)MediaType.Video || v.MediaTypeId == (int)MediaType.Image) && v.Height == null) select v); // First progress report contains the total count. Subsequent reports contain the quantity completed. loadingMediaInfoCount = Query.Count(); if (loadingMediaInfoProgress != null) loadingMediaInfoProgress.Report(loadingMediaInfoCount); int ItemsCompleted = 0; string DefaultFileName; string FilePath; DefaultMediaPath PathCalc = new DefaultMediaPath(); PathCalc.LoadData(); MediaInfoReader MediaInfo = new MediaInfoReader(); foreach (Media item in Query) { // Try to auto-attach file if default file name exists. if (item.FileName == null) { DefaultFileName = PathCalc.GetDefaultFileName(item.Artist, item.Title, item.MediaCategoryId, item.MediaType); foreach (string ext in Settings.GetMediaTypeExtensions(item.MediaType)) { FilePath = Settings.NaturalGroundingFolder + DefaultFileName + ext; if (File.Exists(FilePath)) { item.FileName = DefaultFileName + ext; HasChanges = true; await Task.Delay(1); break; } } } // Load media file to set Length, Width and Height. if (item.FileName != null && await MediaInfo.LoadInfoAsync(item)) HasChanges = true; // Send update with the quantity of files completed. if (loadingMediaInfoProgress != null) loadingMediaInfoProgress.Report(++ItemsCompleted); } MediaInfo.Dispose(); if (HasChanges) context.SaveChanges(); } isLoadingMediaInfo = false; loadingMediaInfoCount = 0; loadingMediaInfoProgress = null; return HasChanges; }
private async Task DownloadCompletedAsync(DownloadItem downloadInfo) { // Separate file extension. string Destination = downloadInfo.Files[0].Destination; string DestinationExt = Path.GetExtension(Destination); Destination = Destination.Substring(0, Destination.Length - Path.GetExtension(Destination).Length); Media video = downloadInfo.Request; if (downloadInfo.Files.Count > 1) { VideoType File1Type = downloadInfo.Files[0].Source.VideoType; AudioType File2Type = downloadInfo.Files[1].Source.AudioType; string File1Ext = GetCodecExtension(File1Type); string File2Ext = GetAudioExtension(File2Type); DestinationExt = GetFinalExtension(File1Type, File2Type); // Make sure output file doesn't already exist. File.Delete(Destination + DestinationExt); // Merge audio and video files. await Task.Run(() => FfmpegBusiness.JoinAudioVideo(Destination + File1Ext, Destination + File2Ext, Destination + DestinationExt, true)); // Delete source files File.Delete(Destination + File1Ext); File.Delete(Destination + File2Ext); } else if (downloadInfo.UpgradeAudio) { // Get original video format. MediaInfoReader MediaReader = new MediaInfoReader(); //await MediaReader.LoadInfoAsync(Settings.NaturalGroundingFolder + downloadInfo.Request.FileName); string VideoDestExt = ".mkv"; //if (MediaReader.VideoFormat == "VP8" || MediaReader.VideoFormat == "VP9") // VideoDestExt = ".webm"; string VideoDest = downloadInfo.Destination + " (extract)" + VideoDestExt; // Keep existing video and upgrade audio. string AudioExt = GetAudioExtension(downloadInfo.Files[0].Source.AudioType); DestinationExt = GetFinalExtension(Path.GetExtension(downloadInfo.Request.FileName), AudioExt); // Merge audio and video files. await Task.Run(() => { FfmpegBusiness.ExtractVideo(Settings.NaturalGroundingFolder + downloadInfo.Request.FileName, VideoDest, true); if (FileHasContent(VideoDest)) FfmpegBusiness.JoinAudioVideo(VideoDest, Destination + AudioExt, Destination + DestinationExt, true); }); // Delete source files File.Delete(VideoDest); File.Delete(Destination + AudioExt); if (FileHasContent(Destination + DestinationExt) && File.Exists(Settings.NaturalGroundingFolder + downloadInfo.Request.FileName)) FileOperationAPIWrapper.MoveToRecycleBin(Settings.NaturalGroundingFolder + downloadInfo.Request.FileName); } // Ensure download and merge succeeded. if (FileHasContent(Destination + DestinationExt)) { // Get final file name. DefaultMediaPath PathCalc = new DefaultMediaPath(); string NewFileName = PathCalc.GetDefaultFileName(video.Artist, video.Title, video.MediaCategoryId, (MediaType)video.MediaTypeId); Directory.CreateDirectory(Path.GetDirectoryName(Settings.NaturalGroundingFolder + NewFileName)); video.FileName = NewFileName + DestinationExt; // Move file and overwrite. if (downloadInfo.Request.FileName != null && File.Exists(Settings.NaturalGroundingFolder + downloadInfo.Request.FileName)) FileOperationAPIWrapper.MoveToRecycleBin(Settings.NaturalGroundingFolder + downloadInfo.Request.FileName); File.Move(Destination + DestinationExt, Settings.NaturalGroundingFolder + video.FileName); } else throw new FileNotFoundException("Audio and video streams could not be merged."); // Add to database EditVideoBusiness Business = new EditVideoBusiness(); Media ExistingData = Business.GetVideoById(video.MediaId); if (ExistingData != null) { // Edit video info. ExistingData.FileName = video.FileName; ExistingData.Length = null; ExistingData.Height = null; Business.Save(); } else { // Add new video info. Business.AddVideo(video); Business.Save(); } downloadInfo.Request.FileName = video.FileName; downloadInfo.Status = DownloadStatus.Done; }
private string GetDefaultFileName() { DefaultMediaPath PathCalc = new DefaultMediaPath(); string Result = PathCalc.GetDefaultFileName(video.Artist, video.Title, video.MediaCategoryId, (MediaType)video.MediaTypeId) + Path.GetExtension(video.FileName); return Result; }
/// <summary> /// Loops through the Media table to set the FileName, Length, Width and Height fields. /// </summary> /// <param name="progress">Reports the progress of the operation. First report is the amount of files to process, then subsequent reports represent the quantity done.</param> /// <returns>Whether some data was modified.</returns> public async Task <bool> LoadMediaInfoAsync(IProgress <int> progress) { // Calling this method when it is already running allows listening to the progress. if (progress != null) { loadingMediaInfoProgress = progress; // First progress report is total count. if (isLoadingMediaInfo) { loadingMediaInfoProgress.Report(loadingMediaInfoCount); } } if (isLoadingMediaInfo) { return(false); } isLoadingMediaInfo = true; bool HasChanges = false; using (Entities context = new Entities()) { // Loop through all media items with missing Length, Width or Height. var Query = (from v in context.Media where v.FileName == null || v.Length == null || ((v.MediaTypeId == (int)MediaType.Video || v.MediaTypeId == (int)MediaType.Image) && v.Height == null) select v); // First progress report contains the total count. Subsequent reports contain the quantity completed. loadingMediaInfoCount = Query.Count(); if (loadingMediaInfoProgress != null) { loadingMediaInfoProgress.Report(loadingMediaInfoCount); } int ItemsCompleted = 0; string DefaultFileName; DefaultMediaPath PathCalc = new DefaultMediaPath(); PathCalc.LoadData(); foreach (Media item in Query) { // Try to auto-attach file if default file name exists. if (item.FileName == null) { DefaultFileName = PathCalc.GetDefaultFileName(item.Artist, item.Title, item.MediaCategoryId, item.MediaType); if (AutoAttachFile(item, DefaultFileName)) { HasChanges = true; } await Task.Delay(1); } // Load media file to set Length, Width and Height. if (item.FileName != null && FileEntryHasMissingInfo(item)) { await LoadFileEntryInfoAsync(item); HasChanges = true; } // Send update with the quantity of files completed. if (loadingMediaInfoProgress != null) { loadingMediaInfoProgress.Report(++ItemsCompleted); } } if (HasChanges) { context.SaveChanges(); } } isLoadingMediaInfo = false; loadingMediaInfoCount = 0; loadingMediaInfoProgress = null; return(HasChanges); }