Example #1
0
        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;
 }
Example #9
0
        /// <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);
        }