AydinAdn/MediaToolkit

Stop and pause.

Opened this issue · 3 comments

Any way to stop or pause the encode proccess an resume later.

Looks like it's possible to suspend the conversion process.
http://stackoverflow.com/questions/71257/suspend-process-in-c-sharp

Being able to pause and resume encoding with breaks in between could be accomplished with some stitching, but might sacrifice storage efficiency, since 2-pass encoding would no longer work on the full file.
https://video.stackexchange.com/a/17062

Not the answer i need. The fact is i need a way to stop or pause the encode process. It has to be in this toolkit, example the stop can be made passing "q" to the ffmpeg proccess right in code using "Process.StandardInput Property" for a soft stop in case it is blocked just kill the process will be ok. For pause the same but passing "p". Sorry my english i just speak spanish...

Update, to pause the process i find this code in Suspend process

///

Converts a non-generic collection to an array.
public static T[] ToArray(this ICollection collection)
{
var items = new T[collection.Count];
collection.CopyTo(items, 0);

return items;

}

using System;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
 
namespace Romy.Core
{
    /// <summary>Suspend/resume a <see cref=”System.Diagnostics.Process”/>,
    /// by suspending or resuming all of its threads.</summary>
    /// <remarks><para>
    /// These methods use the <see cref=”CollectionExtensions.ToArray&lt;T&gt;”/> extension method
    /// on <b>ICollection</b> to convert a <b>ProcessThreadCollection</b> to an array.</para>
    /// <para>
    /// The threads are suspended/resumed in parallel for no particular reason, other than the hope
    /// that it may be better to do so as close to all at once as we can.</para></remarks>
    public static class ProcessExtensions
    {
        #region Methods
 
        public static void Suspend(this Process process)
        {
            Action<ProcessThread> suspend = pt =>
            {
                var threadHandle = NativeMethods.OpenThread(ThreadAccess.SUSPEND_RESUME, false, (uint)pt.Id);
 
                if (threadHandle != IntPtr.Zero)
                {
                    try
                    {
                        NativeMethods.SuspendThread(threadHandle);
                    }
                    finally
                    {
                        NativeMethods.CloseHandle(threadHandle);
                    }
                };
            };
 
            var threads = process.Threads.ToArray<ProcessThread>();
 
            if (threads.Length > 1)
            {
                Parallel.ForEach(threads, new ParallelOptions { MaxDegreeOfParallelism = threads.Length }, pt =>
                {
                    suspend(pt);
                });
            }
            else
            {
                suspend(threads[0]);
            }
        }
 
        public static void Resume(this Process process)
        {
            Action<ProcessThread> resume = pt =>
            {
                var threadHandle = NativeMethods.OpenThread(ThreadAccess.SUSPEND_RESUME, false, (uint)pt.Id);
 
                if (threadHandle != IntPtr.Zero)
                {
                    try
                    {
                        NativeMethods.ResumeThread(threadHandle);
                    }
                    finally
                    {
                        NativeMethods.CloseHandle(threadHandle);
                    }
                }
            };
 
            var threads = process.Threads.ToArray<ProcessThread>();
 
            if (threads.Length > 1)
            {
                Parallel.ForEach(threads, new ParallelOptions { MaxDegreeOfParallelism = threads.Length }, pt =>
                {
                    resume(pt);
                });
            }
            else
            {
                resume(threads[0]);
            }
        }
 
        #endregion
 
        #region Interop
 
        static class NativeMethods
        {
            [DllImport(“kernel32.dll”)]
            [return: MarshalAs(UnmanagedType.Bool)]
            public static extern bool CloseHandle(IntPtr hObject);
 
            [DllImport(“kernel32.dll”)]
            public static extern IntPtr OpenThread(ThreadAccess dwDesiredAccess, bool bInheritHandle, uint dwThreadId);
 
            [DllImport(“kernel32.dll”)]
            public static extern uint SuspendThread(IntPtr hThread);
 
            [DllImport(“kernel32.dll”)]
            public static extern uint ResumeThread(IntPtr hThread);
        }
 
        [Flags]
        enum ThreadAccess : int
        {
            TERMINATE = (0x0001),
            SUSPEND_RESUME = (0x0002),
            GET_CONTEXT = (0x0008),
            SET_CONTEXT = (0x0010),
            SET_INFORMATION = (0x0020),
            QUERY_INFORMATION = (0x0040),
            SET_THREAD_TOKEN = (0x0080),
            IMPERSONATE = (0x0100),
            DIRECT_IMPERSONATION = (0x0200)
        }
 
        #endregion
    }
}