示例#1
1
        private void runTask(videoTask t, Process process)
        {
            this.rsForm.setPercent("0.0");
            this.rsForm.setTime("");
            this.rsForm.setFps("");
            this.rsForm.setEta("");

            string fp = t.getFP();

            process = new System.Diagnostics.Process();

            process.StartInfo.FileName = "cmd";

            // 必须禁用操作系统外壳程序
            process.StartInfo.UseShellExecute        = false;
            process.StartInfo.CreateNoWindow         = true;
            process.StartInfo.RedirectStandardError  = true;
            process.StartInfo.RedirectStandardOutput = true;
            process.StartInfo.RedirectStandardInput  = true;

            process.ErrorDataReceived  += new DataReceivedEventHandler(OutputHandler);
            process.OutputDataReceived += new DataReceivedEventHandler(OutputHandler);

            process.Start();

            this.PIDs[0]    = process.Id;
            this.rsForm.PID = process.Id;
            this.rsForm.setStopBtnState(true);

            // 找到预设存储的文件并提取到taskSetting中
            string      tsfp = System.Windows.Forms.Application.StartupPath + "\\taskSettings\\" + t.getSetting() + ".json";
            taskSetting ts   = JsonConvert.DeserializeObject <taskSetting>(File.ReadAllText(tsfp));

            // 将encoder信息传给信息显示界面
            this.rsForm.encodingProgram = ts.encoder;
            this.rsForm.HideVideoEncoderSetting();

            cmdCode c = new cmdCode(fp, ts, this.outputFolderPath);
            string  cmd;

            int type     = c.taskType();
            int checkNum = 0;

            int       beforeProcessCheckTime = 3500;
            int       processCheckInterval   = 1000;
            const int checkF = 20;

            // 定义一个内部(匿名)方法
            // 整个视频转换过程结束时
            InnerMethodDelagate afterSuccess = delegate()
            {
                this.finishedNum++;
                this.rsForm.setStatusBarFilesCountLabel(this.finishedNum, this.num);

                try
                {
                    process.CancelErrorRead();
                    process.CancelOutputRead();
                }
                catch (Exception e)
                {
                    //saveLog2File();
                }

                this.rsForm.setEta("");
                this.rsForm.setFps("");
                this.rsForm.setTime("");
                this.rsForm.setEstKbps("");
                this.rsForm.SetTaskStepsLabel(true);

                Process p = Process.GetProcessById(this.PIDs[0]);
                p.Kill();
                this.rsForm.setStopBtnState(false);
                this.rsForm.setPercent("-3");
                this.isfinished[0] = true;
                this.reportCount   = 0;
                this.log.Clear();

                miniLog += t.getFP() + Environment.NewLine + Environment.NewLine + Environment.NewLine;
                saveMiniLog2File();
            };

            // 运行失败时调用
            InnerMethodDelagate afterFailed = delegate()
            {
                this.isfailed = true;

                saveLog2File();

                this.rsForm.setPercent("-1");
                this.rsForm.setTime("发生错误");
                this.rsForm.setFps("日志保存在程序目录");

                int sleepTime = 5;  // 设置失败后继续下一个任务的时间
                this.rsForm.setEta(sleepTime.ToString() + "秒后继续运行");

                this.rsForm.setStatusBarLabelTextColorRED();
                this.finishedNum++;
                this.rsForm.setStatusBarFilesCountLabel(this.finishedNum, this.num);
                this.rsForm.HideVideoEncoderSetting();

                try
                {
                    process.CancelErrorRead();
                    process.CancelOutputRead();
                }
                catch (Exception e)
                {
                    //saveLog2File();
                }

                Thread.Sleep(sleepTime * 1000);

                Process p = Process.GetProcessById(this.PIDs[0]);
                p.Kill();
                this.rsForm.setStopBtnState(false);
                this.rsForm.setPercent("-3");
                this.isfinished[0] = true;
                this.reportCount   = 0;
                this.log.Clear();
            };

            // 视频编码前更新UI(显示视频总帧数)
            InnerMethodDelagate DispVideoFrames = delegate()
            {
                // MediaInfo读取视频帧数
                MediaInfo MI = new MediaInfo();
                string    duration;
                string    frameRate;
                string    frames;
                MI.Open(t.getFP());
                duration = MI.Get(StreamKind.Video, 0, "Duration");
                try
                {
                    double totalTime = Double.Parse(duration) / 1000.0;
                    frameRate = MI.Get(StreamKind.Video, 0, "FrameRate");
                    frames    = ((int)(totalTime * Double.Parse(frameRate))).ToString();

                    if (!String.IsNullOrWhiteSpace(frames))
                    {
                        this.rsForm.setTime("0/" + frames);
                    }
                }
                catch (Exception e)
                {
                    //saveLog2File();
                }
            };

            InnerMethodDelagate VideoEncode = delegate()
            {
                // 视频编码
                this.encoding = true;
                this.rsForm.setPercent("0.0");

                string ext = this.getFileExtName(t.getFP());
                if (String.Equals(ext, "avs", StringComparison.CurrentCultureIgnoreCase))
                {
                    this.videoType = AVS;
                }
                else
                {
                    this.videoType = NORMAL;
                    DispVideoFrames();
                }

                cmd = c.cmdCodeGenerate(VIDEOENCODE, this.videoType);
                process.StandardInput.WriteLine(cmd);

                try
                {
                    process.BeginErrorReadLine();
                    process.BeginOutputReadLine();
                }
                catch (Exception e)
                {
                    //saveLog2File();
                }

                checkNum         = 0;
                this.reportCount = 0;
                int cpx2 = this.checkPattern + this.checkPattern;
                for (int i = 0; i < cpx2; i++)
                {
                    checkFrame[i] = 0;
                }
                for (int i = 0; i < cpx2; i++)
                {
                    this.fps[i] = 0;
                }

                Thread.Sleep(beforeProcessCheckTime);

                Process p;
                switch (videoType)
                {
                case NORMAL:
                    p = GetSubTaskProcess(ts.encoder);
                    if (p != null)
                    {
                        this.subTaskPID = p.Id;
                    }
                    else
                    {
                        this.subTaskPID = -1;
                    }
                    break;

                case AVS:
                    Process avsP  = GetSubTaskProcess("avs4x265.exe");
                    int     avsId = avsP.Id;
                    if (avsP != null)
                    {
                        bool hasFound = false;

                        // 等待视频编码进程启动,最长等待1小时
                        for (int i = 0; i < 7200; i++)
                        {
                            // 确认avs进程仍在运行
                            try
                            {
                                Process.GetProcessById(avsId);
                            }
                            catch (Exception e)
                            {
                                if (this.encoding == true || ConfirmFailed())
                                {
                                    afterFailed();
                                }
                                return;
                            }

                            // 每隔500ms寻找视频编码进程
                            p = GetSubTaskProcess(ts.encoder, avsId);
                            if (p != null)
                            {
                                this.subTaskPID = p.Id;
                                hasFound        = true;
                                break;
                            }
                            else
                            {
                                Thread.Sleep(500);
                            }
                        }

                        if (!hasFound)
                        {
                            this.subTaskPID = -1;
                        }
                    }
                    else
                    {
                        this.subTaskPID = -1;
                    }
                    break;

                default:
                    break;
                }

                this.rsForm.ShowVideoEncoderSetting();

                while (this.encoding == true || this.postProcessing == true)
                {
                    try
                    {
                        Process.GetProcessById(this.subTaskPID);
                    }
                    catch (Exception e)
                    {
                        if (this.encoding == true || ConfirmFailed())
                        {
                            afterFailed();
                        }
                        return;
                    }

                    Thread.Sleep(processCheckInterval);
                }
                try
                {
                    process.CancelErrorRead();
                    process.CancelOutputRead();
                }
                catch (Exception e)
                {
                    //saveLog2File();
                }

                this.rsForm.HideVideoEncoderSetting();
            };

            InnerMethodDelagate Mux = delegate()
            {
                // muxer
                this.muxing = true;
                int stepIdx = type == ONLYVIDEO ? 2 : 3;
                this.rsForm.SetTaskStepsLabel(false, stepIdx, stepIdx, MUXER);

                cmd = c.cmdCodeGenerate(MUXER);
                process.StandardInput.WriteLine(cmd);

                try
                {
                    process.BeginErrorReadLine();
                    process.BeginOutputReadLine();
                }
                catch (Exception e)
                {
                    //saveLog2File();
                }

                checkNum = 0;

                Thread.Sleep(beforeProcessCheckTime);  // 有些超短的视频(1-2M),如果不加这句就会直接判定为任务已失败,疑似原因:没等判断完进程就已经结束

                string muxerProcessName = "";
                if (String.Equals("mp4", ts.outputFormat))
                {
                    muxerProcessName = "mp4Box";
                }
                else if (String.Equals("mkv", ts.outputFormat))
                {
                    muxerProcessName = "mkvmerge";
                }

                Process p = GetSubTaskProcess(muxerProcessName);
                if (p != null)
                {
                    this.subTaskPID = p.Id;
                }
                else
                {
                    this.subTaskPID = -1;
                }

                while (this.muxing == true)
                {
                    try
                    {
                        Process.GetProcessById(this.subTaskPID);
                    }
                    catch (Exception e)
                    {
                        Thread.Sleep(1000);
                        if (this.muxing == true)
                        {
                            afterFailed();
                        }
                        return;
                    }

                    Thread.Sleep(processCheckInterval);
                    //checkNum = checkCmdRunning(checkNum, checkF);
                    //if (checkNum == -1)
                    //{
                    //    return;
                    //}
                }

                afterSuccess();

                string tempVideoFp = c.cmdCodeGenerate(DELETEVIDEOTEMP);
                string tempAudioFp = c.cmdCodeGenerate(DELETEAUDIOTEMP);
                try
                {
                    File.Delete(tempVideoFp);
                    File.Delete(tempAudioFp);
                }
                catch (System.IO.IOException ex)
                {
                    this.log.AppendLine("出现异常:" + ex);
                    saveLog2File();
                }
            };

            // 音频编码或复制开始前更新UI(显示音频总时长)
            InnerMethodDelagate DispAudioDuration = delegate()
            {
                // MediaInfo读取音频时长
                MediaInfo MI = new MediaInfo();
                string    duration;
                MI.Open(c.getAudioSource());
                duration = MI.Get(StreamKind.Audio, 0, 69);

                if (!String.IsNullOrWhiteSpace(duration))
                {
                    this.rsForm.setTime("0/" + duration);
                }

                this.rsForm.setPercent("0.0", AUDIOENCODE);
            };

            InnerMethodDelagate ClearUIAfterAudioProcessing = delegate()
            {
                this.rsForm.setPercent("0.0");
                this.rsForm.setTime("");
                this.rsForm.setFps("");
            };

            switch (type)
            {
            case ONLYVIDEO:

                this.rsForm.SetTaskStepsLabel(false, 1, 2, VIDEOENCODE);

                VideoEncode();

                // 一个子任务失败了意味着这个文件的编码任务失败,所以在所有子任务开始时都要检查checkNum是否为-1
                if (isfailed)
                {
                    return;
                }
                //afterSuccess();

                Mux();

                break;

            case COPYAUDIO:
                // 复制音频
                cmd = c.cmdCodeGenerate(AUDIOCOPY);
                process.StandardInput.WriteLine(cmd);
                process.BeginErrorReadLine();
                process.BeginOutputReadLine();
                this.audioProcessing = true;
                this.rsForm.SetTaskStepsLabel(false, 1, 3, AUDIOCOPY);
                DispAudioDuration();

                checkNum = 0;

                Thread.Sleep(beforeProcessCheckTime);

                Process p = GetSubTaskProcess("ffmpeg");
                if (p != null)
                {
                    this.subTaskPID = p.Id;
                }
                else
                {
                    this.subTaskPID = -1;
                }

                while (this.audioProcessing == true)
                {
                    try
                    {
                        Process.GetProcessById(this.subTaskPID);
                    }
                    catch (Exception e)
                    {
                        Thread.Sleep(1000);
                        if (this.audioProcessing == true)
                        {
                            afterFailed();
                        }
                        return;
                    }

                    Thread.Sleep(processCheckInterval);
                    //checkNum = checkCmdRunning(checkNum, checkF);
                    //if (checkNum == -1)
                    //{
                    //    return;
                    //}
                }
                ClearUIAfterAudioProcessing();

                process.CancelErrorRead();
                process.CancelOutputRead();

                this.rsForm.SetTaskStepsLabel(false, 2, 3, VIDEOENCODE);

                // 一个子任务失败了意味着这个文件的编码任务失败,所以在所有子任务开始时都要检查checkNum是否为-1
                if (isfailed)
                {
                    return;
                }
                VideoEncode();

                // 一个子任务失败了意味着这个文件的编码任务失败,所以在所有子任务开始时都要检查checkNum是否为-1
                if (isfailed)
                {
                    return;
                }
                Mux();

                break;

            case SUPPRESSAUDIO:
                // 音频编码
                cmd = c.cmdCodeGenerate(AUDIOENCODE);
                process.StandardInput.WriteLine(cmd);
                process.BeginErrorReadLine();
                process.BeginOutputReadLine();
                this.audioProcessing = true;
                this.rsForm.SetTaskStepsLabel(false, 1, 3, AUDIOENCODE);
                DispAudioDuration();

                checkNum = 0;

                Thread.Sleep(beforeProcessCheckTime);

                Process p2 = GetSubTaskProcess(ts.audioEncoder);
                if (p2 != null)
                {
                    this.subTaskPID = p2.Id;
                }
                else
                {
                    this.subTaskPID = -1;
                }

                while (this.audioProcessing == true)
                {
                    try
                    {
                        Process.GetProcessById(this.subTaskPID);
                    }
                    catch (Exception e)
                    {
                        Thread.Sleep(1000);
                        if (this.audioProcessing == true)
                        {
                            afterFailed();
                        }
                        return;
                    }

                    Thread.Sleep(processCheckInterval);
                    //checkNum = checkCmdRunning(checkNum, checkF);
                    //if (checkNum == -1)
                    //{
                    //    return;
                    //}
                }
                ClearUIAfterAudioProcessing();

                process.CancelErrorRead();
                process.CancelOutputRead();

                this.rsForm.SetTaskStepsLabel(false, 2, 3, VIDEOENCODE);

                // 一个子任务失败了意味着这个文件的编码任务失败,所以在所有子任务开始时都要检查checkNum是否为-1
                if (isfailed)
                {
                    return;
                }
                VideoEncode();

                // 一个子任务失败了意味着这个文件的编码任务失败,所以在所有子任务开始时都要检查checkNum是否为-1
                if (isfailed)
                {
                    return;
                }
                Mux();

                break;

            default:
                cmd = "";
                break;
            }

            //MessageBox.Show(cmd);
        }
示例#2
0
        private void threadRun(int threadIndex)
        {
            videoTask t = rp.getTask();
            videoTask next;

            for (int i = 0; i < this.num; i++)
            {
                this.isfailed = false;                  // 将任务失败状态设为否
                if (i != 0)
                {
                    rp.removeTask(t, false);            // false表示成功完成编码没有失败
                }

                this.runTask(t, this.rsForm.process);

                next = rp.getTask();                    // get之后任务已从运行池的等待队列中pop出了,无需再次get
                //MessageBox.Show(next.printTask());
                if (next == null)
                {
                    rp.removeTask(t, false);
                    break;
                }
                t = next;
            }
        }
        // !!点击开始转换
        private void StartBtn_Click(object sender, EventArgs e)
        {
            if (this.fileListView.Items.Count == 0)
            {
                string noFileMsg = "未添加任何文件";
                MessageBox.Show(noFileMsg);
            }
            else
            {
                if (checkSettingChange() == -1)
                {
                    MessageBox.Show("一个或多个任务的预设已被删除,请重新添加预设!");
                    return;
                }

                if (checkSettingChange() == 1) // 1为真,表示有变化
                {
                    string       note = "检测到预设已修改,是否覆盖当前选中的预设?\n点击“确定”将覆盖并应用该预设到全部任务。点击“取消”将中止任务且不做改动。";
                    DialogResult dr   = MessageBox.Show(note, "检测到预设修改", MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
                    if (dr == DialogResult.OK)
                    {
                        //点确定的代码
                        saveSetting2File(this.encodeSettingCB.Text);
                        readAllSettingsFromFiles();

                        for (int i = 0; i < this.fileListView.Items.Count; i++)
                        {
                            fileListView.Items[i].SubItems[1].Text = this.encodeSettingCB.Text;
                        }
                    }
                    else
                    {
                        //点取消的代码
                        return;
                    }
                }

                int             count = fileListView.Items.Count;
                filePathStorage q     = new filePathStorage(count);
                for (int i = 0; i < count; i++)
                {
                    if (!CheckSettingExist(fileListView.Items[i].SubItems[1].Text))
                    {
                        MessageBox.Show("一个或多个任务的预设已被删除,请检查编码设置!");
                        return;
                    }

                    // subitems[2]中保存着完整文件名
                    videoTask t = new videoTask(fileListView.Items[i].SubItems[2].Text, fileListView.Items[i].SubItems[1].Text);
                    q.add(t);
                }

                this.j = new Job(q);
                //this.j.ErrorEvent += DisposeJob;
                this.j.runJob(this.outputFilePathTB.Text);
            }
        }
 public void add(videoTask t)
 {
     lock (lockObj)
     {
         // 在队列中添加
         // 此处不判断队列是否为满,请在上层对象中加以判断
         this.tQueue[this.rear] = t;
         this.rear = (this.rear + 1) % (this.max + 1);
         this.length++;  // 长度+1
     }
 }
示例#5
0
 public void removeTask(videoTask t, bool isfailed)
 {
     // 移动到指定的队列
     if (!isfailed)
     {
         this.completedQueue.add(t);
     }
     else
     {
         this.failedQueue.add(t);
     }
 }
示例#6
0
        public videoTask getTask()
        {
            // 取一个任务(取出后该任务即从队列中移除了)
            videoTask t = this.waitingQueue.pop();

            if (t != null)
            {
                // 赋config值
                //t.setConfig();

                return(t);
            }
            return(t);  // 如果未取得task,返回null,交job处理
        }
 public void add(videoTask t)
 {
     try
     {
         if (this.count == maxCount)
         {
             throw new Exception("Overflow");
         }
         else
         {
             this.storage[count++] = t;
         }
     }
     catch (Exception ex)
     {
         MessageBox.Show("Error: Could not add any more tasks. Original error: " + ex.Message);
     }
 }
        public videoTask pop()
        {
            lock (lockObj)  // 锁定,不允许其他线程同时运行这段代码
            {
                // 取出队首Task并且从队列中移除
                if (this.front == this.rear)
                {
                    return(null);  // 队列为空返回null由运行池处理
                }
                else
                {
                    videoTask x = this.tQueue[this.front];
                    this.front = (this.front + 1) % (this.max + 1);

                    this.length--;  // 长度-1
                    return(x);
                }
            }
        }