Пример #1
0
        /// <summary>
        /// For files encoded in various segments (stop/resume), merge the various segments.
        /// </summary>
        private CompletionStatus MergeSegments(MediaEncoderSettings settings, string destination)
        {
            MediaEncoderSegments segBusiness = new MediaEncoderSegments();

            segBusiness.Analyze(settings);
            if (segBusiness.SegLeft.Count() > 0)
            {
                return(CompletionStatus.Error);
            }

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

            foreach (SegmentInfo seg in segBusiness.SegDone)
            {
                SegmentList.Add(PathManager.GetOutputFile(settings.JobIndex, seg.Start, settings.Container));
            }

            CompletionStatus Result = CompletionStatus.Success;

            File.Delete(destination);
            if (SegmentList.Count == 1)
            {
                File.Move(SegmentList[0], destination);
            }
            else if (SegmentList.Count > 1)
            {
                Result = MediaMuxer.Concatenate(SegmentList, destination, new ProcessStartOptions(settings.JobIndex, "Merging Files", false));
            }
            settings.CompletionStatus = Result;
            return(Result);
        }
Пример #2
0
 /// <summary>
 /// Prepares the files of an existing job.
 /// </summary>
 /// <returns>A MediaEncoderSegments object containing the segments analysis.</returns>
 public MediaEncoderSegments PrepareExistingJob(MediaEncoderSettings settings)
 {
     settings.ResumePos        = 0;
     settings.CompletionStatus = CompletionStatus.Success;
     if (File.Exists(settings.FinalFile))
     {
         // Merging was completed.
         return(null);
     }
     else
     {
         MediaEncoderSegments SegBusiness = new MediaEncoderSegments();
         SegBusiness.Analyze(settings);
         return(SegBusiness);
     }
 }
Пример #3
0
        private void EncoderThread(object obj)
        {
            MediaEncoderSettings settings = obj as MediaEncoderSettings;

            settings.CompletionStatus = CompletionStatus.Success;
            DateTime StartTime = DateTime.Now;

            FFmpegConfig.UserInterfaceManager.Start(settings.JobIndex, "Processing Video");

            MediaEncoderSegments SegBusiness = PrepareExistingJob(settings);

            // If merging is completed, SegBusiness==null. If work is completed but not merged, SegBusiness.SegLeft = empty list.
            if (SegBusiness != null && SegBusiness.SegLeft.Count() > 0)
            {
                if (settings.Deshaker && (settings.DeshakerSettings.PrescanAction != PrescanType.Full || !settings.DeshakerSettings.PrescanCompleted))
                {
                    settings.DeshakerSettings.PrescanAction = PrescanType.Full;
                    settings.CompletionStatus = GenerateDeshakerLog(settings, settings.InputFile);
                }

                if (settings.CompletionStatus == CompletionStatus.Success)
                {
                    // Encode audio stream
                    Task EncAudio = null;
                    if (settings.HasAudioOptions)
                    {
                        EncAudio = Task.Run(() => EncoderBusiness.EncodeAudio(settings));
                    }

                    // Encode video stream in segments
                    List <Task <CompletionStatus> > EncTasks = new List <Task <CompletionStatus> >();
                    if (settings.VideoAction != VideoAction.Copy)
                    {
                        bool Cancel = false;
                        foreach (SegmentInfo seg in SegBusiness.SegLeft)
                        {
                            MediaEncoderSettings EncSettings = settings.Clone();
                            EncSettings.ResumePos = seg.Start;
                            File.Delete(EncSettings.OutputFile);
                            EncTasks.Add(Task.Run(() => EncoderBusiness.EncodeVideo(EncSettings, seg.Length, SegBusiness.TotalFrames)));

                            // If there are more segments than max parallel instances, wait until some threads finish
                            if (EncTasks.Count >= settings.ParallelProcessing)
                            {
                                Task.WaitAny(EncTasks.ToArray());
                                foreach (var item in EncTasks.ToArray())
                                {
                                    if (item.IsCompleted)
                                    {
                                        if (item.Result == CompletionStatus.Success)
                                        {
                                            EncTasks.Remove(item);
                                        }
                                        else
                                        {
                                            settings.CompletionStatus = item.Result;
                                            Cancel = true;
                                        }
                                    }
                                }
                            }
                            if (Cancel)
                            {
                                break;
                            }
                        }
                    }

                    EncAudio?.Wait();
                    Task.WaitAll(EncTasks.ToArray());
                }
            }
            else if (settings.CompletionStatus == CompletionStatus.None)
            {
                settings.CompletionStatus = CompletionStatus.Success;
            }

            if (FFmpegConfig.UserInterfaceManager.AppExited)
            {
                return;
            }

            // Check if encode is completed.
            EncodingCompletedEventArgs CompletedArgs = null;

            if (settings.CompletionStatus == CompletionStatus.Success)
            {
                CompletedArgs = FinalizeEncoding(settings, StartTime);
                if (settings.CompletionStatus == CompletionStatus.Success && CompletedArgs != null)
                {
                    EncodingCompleted?.Invoke(this, CompletedArgs);
                }
            }
            if (settings.CompletionStatus != CompletionStatus.Success)
            {
                CompletedArgs = GetEncodingResults(settings, null, StartTime);
                if (IsEncoding)
                {
                    EncodingFailed?.Invoke(this, CompletedArgs);
                }
            }

            if (IsEncoding || settings.CompletionStatus == CompletionStatus.Success)
            {
                Application.Current.Dispatcher.Invoke(() => ProcessingQueue.Remove(settings));
            }

            FFmpegConfig.UserInterfaceManager.Stop(settings.JobIndex);

            // Start next job.
            if (IsEncoding && ProcessingQueue.Count > 0)
            {
                EncoderThread(ProcessingQueue.First());
            }

            JobThread = null;
        }