Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CreateProcess fails when dshow is used in commandline

Tags:

c++

ffmpeg

winapi

Trying to launch ffmpeg using CreateProcess.

Issues:

1) Can't use dshow in the commandline.

2) RTMP streaming with the STDIN piped don't show the stream.

Questions:

1) What are the ceveats in the commandline pertaining to CreateProcess api?

2) What's is the way round ? How can the issue be fixed?

This code works:

BOOL bSuccess = CreateProcess(NULL,
    L"ffmpeg.exe -y -loop 1 -i kites.jpg  out.mp4",         
    NULL,   
    NULL,
    TRUE, 
    CREATE_NEW_CONSOLE, 
    NULL, 
    NULL,
    &siStartInfo,
    &piProcInfo);

CreateProcess fails when dshow is used. However it works as command line in console.

BOOL bSuccess = CreateProcess(NULL,
    L"ffmpeg.exe -y -loop 1 -i kites.jpg  -f dshow  -i audio=\"Stereo Mix(Realtek High Definition Audio)\"  out.mp4",
    NULL,
    NULL,
    TRUE,
    CREATE_NEW_CONSOLE,
    NULL,
    NULL,
    &siStartInfo,
    &piProcInfo);

Edited: ( with absolute path, still no luck)

std::wstring cmdArgslistSetChannel = L"ffmpeg.exe -y -loop 1 -i c:\test\kites.jpg  -f dshow  -i audio=\"Stereo Mix(Realtek High Definition Audio)\"  out.mp4";
bSuccess = CreateProcess(NULL, 
        &cmdArgslistSetChannel[0],
        NULL,          
        NULL,          
        TRUE,          
        CREATE_NEW_CONSOLE,            
        NULL,          
        NULL,          
        &siStartInfo, 
        &piProcInfo);  
like image 362
ark1974 Avatar asked Jun 25 '19 03:06

ark1974


2 Answers

You are almost there. You can specify the absolute path like so. Make sure the no whitespaces are present in the folder name, else ffmpeg command may fail again. If the ffmpeg is situated in another folder, you should specify the path too.

std::wstring cmdArgslistSetChannel = L"c:\test\ffmpeg.exe -y -loop 1 -i \"c:\\test\\kites.jpg\"  -f dshow  -i audio=\"Stereo Mix(Realtek High Definition Audio)\"  out.mp4";
like image 152
seccpur Avatar answered Sep 30 '22 12:09

seccpur


First,

The immediate issue is simply that you need to escape backslashes.

Change:

c:\test\kites.jpg 

To

c:\\test\\kites.jpg

'\t' is a tab and '\' is a backslash

Second,

from Comment:

From CreateProcessW: "The Unicode version of this function, CreateProcessW, can modify the contents of [the lpCommandLine] string. Therefore, this parameter cannot be a pointer to read-only memory (such as a const variable or a literal string). If this parameter is a constant string, the function may cause an access violation."

Therefore you need to hold the contents in a buffer like this:

std::wstring args{L"c:\test\ffmpeg.exe -y -loop 1 -i \"c:\\test\\kites.jpg\"  -f dshow  -i audio=\"Stereo Mix(Realtek High Definition Audio)\"  out.mp4"};

Third,

if you know full path to the executable (which it seems), you can benefit from putting that into the first parameter of CreateProcess instead. This will give you a little more control and diagnostics (in the future as well) as it is a more direct way of creating the process.

like image 30
darune Avatar answered Sep 30 '22 11:09

darune