【问题标题】:PHP execute batch files to start recording ffmpeg and to kill ffmpegPHP执行批处理文件开始记录ffmpeg并杀死ffmpeg
【发布时间】:2018-02-18 00:36:20
【问题描述】:

您好,我只是想知道是否有人知道我可以运行包含多个“启动 ffmpeg”命令的批处理文件的方法,这允许我在某个随机时间点使用批处理文件将其杀死。

我有一批从 rtsp 提要开始录制 4 个视频到文件。另一个任务杀死了 ffmpeg 进程。问题是我可以通过在 cmd 提示符下运行来成功运行这些,但是当我尝试使用 exec(record.bat) 或 popen() 等时,它会在后台运行 ffmpeg 进程,而 stoprecord.bat 不能杀死它的错误是:

The Process with PID x <child process of PID y> could not be terminated.


Reason: This Process can only be termintated forcefully (with /f option)

我不想强制它,因为当你强制关闭它时,mp4 文件会损坏。当我直接运行 bat 文件时,我不需要那个 force 选项。我已经尝试为 IIS_IUSRS 用户授予文件夹完全权限,我已将 bat 和文件夹创建者设为 IIS_IUSRS(认为批处理中的 mkdir 不允许将视频录制到 IIS usr)。

任何人都知道为什么这不起作用。我已将 bat 文件和调用它们的 php 脚本放在下面。

Record.bat

cd C:\inetpub\wwwroot\ESTF\batch
tasklist /FI "IMAGENAME eq ffmpeg_sr.exe" | find ":" > NUL
if errorlevel 1 exit
set MEDIA_DIR=C:\inetpub\wwwroot\ESTF\media\recordings
set WEB_DIR=C:\inetpub\wwwroot\estf\
set VLC_DIR=C:\Program Files\VideoLAN\VLC
set ROOM=simroom
set M=1
set N=1
set CURRENT_DAY=day1
set FFMPEG_DIR=C:\inetpub\wwwroot\ESTF\ffmpeg\bin                
call "date.bat"
if not exist %MEDIA_DIR%\curDate.txt (
    mkdir %MEDIA_DIR%
    icacls %MEDIA_DIR% /grant Everyone:(f)
    echo %DATESTR%>%MEDIA_DIR%\curDate.txt
    echo %CURRENT_DAY%>%MEDIA_DIR%\curDay.txt
    goto :LOOP2
)
if exist %MEDIA_DIR%\curDate.txt (
    set /p STORED_DATE=<C:\inetpub\wwwroot\ESTF\media\recordings\curDate.txt
)

if /I %STORED_DATE%==%DATESTR% (
        set /p CURRENT_DAY=<C:\inetpub\wwwroot\ESTF\media\recordings\curDay.txt
        goto :LOOP2
)
if /I NOT %STORED_DATE%==%DATESTR% (
    echo %DATESTR%>%MEDIA_DIR%\curDate.txt
    goto :LOOP1
)

:LOOP1
    set DAY_LOOP=%MEDIA_DIR%\day%M%
    if exist %DAY_LOOP% (
        set /a M = %M%+1
        goto :LOOP1
    )
    if not exist %DAY_LOOP% (
        mkdir %DAY_LOOP%
        icacls %DAY_LOOP% /grant Everyone:(f)
    )
    set CURRENT_DAY=day%M%
    @echo %CURRENT_DAY%>%MEDIA_DIR%\curDay.txt

:LOOP2
    set CURRENT_ROOM=%MEDIA_DIR%\%CURRENT_DAY%\%ROOM%\Team%N%
    if exist %CURRENT_ROOM% (
        set /a N = %N%+1
        goto :LOOP2
    )
    if not exist %CURRENT_ROOM% (
        mkdir %CURRENT_ROOM%
        icacls %CURRENT_ROOM% /grant Everyone:(f)
    )

cd %FFMPEG_DIR%

echo %CURRENT_ROOM%>%MEDIA_DIR%\%CURRENT_DAY%\%ROOM%\teamNo.txt
echo recording>%WEB_DIR%\srRecording.txt
start ffmpeg_sr  -i rtsp://192.168.0.50:554/Streaming/Channels/1 -c:v copy -c:a libmp3lame -strict experimental "%CURRENT_ROOM%\1.mp4"
start ffmpeg_sr  -i rtsp://192.168.0.51:554/Streaming/Channels/1 -c:v copy "%CURRENT_ROOM%\2.mp4"
start ffmpeg_sr  -i rtsp://192.168.0.52:554/Streaming/Channels/1 -c:v copy "%CURRENT_ROOM%\3.mp4"
start ffmpeg_sr  -i rtsp://192.168.0.21:554/Streaming/Channels/1 -c:v copy "%CURRENT_ROOM%\4.mp4"
start ffmpeg_sr -f dshow -i audio="Microphone (High Definition Audio Device)" -c:a libmp3lame -strict experimental "%CURRENT_ROOM%\0.mp3"
exit

Stoprecord.bat

taskkill /im ffmpeg_sr.exe /t
set WEB_DIR=c:\inetpub\wwwroot\estf\
set FFMPEG_DIR=C:\inetpub\wwwroot\ESTF\ffmpeg\bin\
echo stopped>%WEB_DIR%\srRecording.txt
set /p CURRENT_DAY=<C:\inetpub\wwwroot\ESTF\media\recordings\curDay.txt
set /p CURRENT_ROOM=<C:\inetpub\wwwroot\ESTF\media\recordings\%CURRENT_DAY%\simroom\teamNo.txt
echo %CURRENT_ROOM%
cd %FFMPEG_DIR%
ffmpeg -i %CURRENT_ROOM%/ -i %CURRENT_ROOM%/0.mp3 -c:v copy -c:a copy -strict experimental -map 0:v:0 -map 1:a:0 %CURRENT_ROOM%/1.mp4
ffmpeg -i %CURRENT_ROOM%/1_temp.mp4 -c:v copy -c:a copy -strict experimental -map 0:v:0 -map 1:a:0 %CURRENT_ROOM%/1.mp4
REM del %CURRENT_ROOM%\1_temp.mp4
del %CURRENT_ROOM%\0.mp3
exit

record.php

<?php
echo exec('whoami');
//$recordPath = 'c:\inetpub\wwwroot\estf\batch\srRecord.bat';
//exec('c:\inetpub\wwwroot\estf\batch\srRecord.bat');
$handle = popen('start c:\inetpub\wwwroot\estf\batch\srRecord.bat exit','r');
pclose($handle);
echo $handle;
?>

stoprecord.php

<?php
//exec('c:\inetpub\wwwroot\estf\batch\srRecordStop.exe /dev/null');
$handle = popen('start c:\inetpub\wwwroot\estf\batch\srRecordStop.bat','r');
pclose($handle);
//die();
echo $handle;
?>

我尝试了exec()、pclose(popen())、shell_exec(),尝试在批处理文件中的php文件和ffmpeg中添加/dev/nul &。

问候,

米切尔

【问题讨论】:

  • 看起来这个问题已经在ffmpeg ticket 中得到了很好的描述。似乎 ffmpeg 已实现向应用程序发送“q”以优雅地停止流录制,但我不知道如何为后台进程执行此操作。也许您可以尝试其他几个二进制文件来优雅地终止您的流:@killnircmd closeprocess
  • 好吧,还有另一种方法可以让我在计算机上运行脚本一段未设置的时间,然后按命令杀死它吗? Telnet、ssh?

标签: php batch-file ffmpeg exec


【解决方案1】:

所以我最终使用了一些东西。首先,我将批处理转换为 exe。然后我在任务计划程序中创建了一个任务。然后我使用 pclose(popen($com,'r'));运行启动exe文件并在桌面上打开ffmpeg进程的任务。

显然不是执行 ffmpeg 的直接途径,但它适用于我的系统。这使我可以创建另一个取消它们的事件(或者只运行 exec(taskkill ffmpeg.exe) 命令。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-08-06
    • 1970-01-01
    • 2023-04-03
    • 2021-05-30
    • 2012-08-25
    • 1970-01-01
    • 2018-06-29
    相关资源
    最近更新 更多