Thread overview
How to read live output from another process ?
Jun 23, 2023
Vinod K Chandran
Jun 29, 2023
Vinod K Chandran
Jun 29, 2023
Ferhat Kurtulmuş
June 23, 2023

Hi all,
I am trying to create a program which burns time codes to a video. I am using ffmpeg for this. So far, I can successfully start ffmpeg in another thread and stop it when I need. But I can't read the live outputs from ffmpeg. This is my code.

void onBtnBurnClick(Control c, EventArgs e) {
	if (!burnStarted) {
		burnStarted = true;
		btnBurn.text = "Stop Burning";
		auto ffCmd = makeFFMPEGCommand(selVideo);
          // ffPipe is a global ProcessPipes
		auto tsk = task!runFFMPEG(ffCmd, &ffPipe, frm.handle);
		tsk.executeInNewThread();
	} else {
		ffPipe.stdin.writeln("q");
		ffPipe.stdin.close();
		btnBurn.text = "Burn Time Code";
	}
}

This is a button's click event.

June 29, 2023

On Friday, 23 June 2023 at 23:37:29 UTC, Vinod K Chandran wrote:

>

Hi all,

Hi, I found the solution by myself. We can use Pipe struct for this job.
Here is the code looks like. This is for future readers.

void onBtnBurnClick(Control c, EventArgs e) { // A button click event handler
	if (!jobStarted) {
		jobStarted = true;
		btnBurn.text = "Stop the job";
		string cmd = makeCommand();
		ff = spawn(&runInAnotherThread, cmd); // ff is global var
	} else {
		ff.send(-1); // Send a signal to stop the job
		btnBurn.text = "Start the job";
	}
}

void runInAnotherThread(string cmd) {
	Duration du = dur!"hnsecs"(-2); // Minus value for no waiting
	auto psin = pipe();
	auto psout = pipe();
	auto pserr = pipe();
	spawnShell(cmd, psin.readEnd, psout.writeEnd, pserr.writeEnd , null, Config.detached);
	string line;
    while ((line = pserr.readEnd.readln()) !is null){
		receiveTimeout(du, (int dummy) {psin.writeEnd.writeln("q"); psin.writeEnd.flush(); }); // Here, entering "q" is app specific command to stop.
		writefln("pipe err: %s", line);
		stdout.flush;
	}
}

By this way, you can asynchronously process the output from the child process.

June 29, 2023

On Friday, 23 June 2023 at 23:37:29 UTC, Vinod K Chandran wrote:

>

Hi all,
I am trying to create a program which burns time codes to a video. I am using ffmpeg for this. So far, I can successfully start ffmpeg in another thread and stop it when I need. But I can't read the live outputs from ffmpeg. This is my code.

void onBtnBurnClick(Control c, EventArgs e) {
	if (!burnStarted) {
		burnStarted = true;
		btnBurn.text = "Stop Burning";
		auto ffCmd = makeFFMPEGCommand(selVideo);
          // ffPipe is a global ProcessPipes
		auto tsk = task!runFFMPEG(ffCmd, &ffPipe, frm.handle);
		tsk.executeInNewThread();
	} else {
		ffPipe.stdin.writeln("q");
		ffPipe.stdin.close();
		btnBurn.text = "Burn Time Code";
	}
}

This is a button's click event.
I used something similar here:

https://github.com/aferust/oclcv/blob/main/examples/threshold-video/source/app.d