精品技术论坛

精品技术论坛 (https://bbs.et8.net/bbs/index.php)
-   『软件使用』 (https://bbs.et8.net/bbs/forumdisplay.php?f=17)
-   -   【求助】能否让一个批处理“同时”运行两个任务?自己研究测试不行,求指点。 (https://bbs.et8.net/bbs/showthread.php?t=1375120)

林展扬 2019-10-02 13:02:32

【求助】能否让一个批处理“同时”运行两个任务?自己研究测试不行,求指点。
 
如题,用批处理压视频,在处理视频流的时候,CPU是压不满的,现在是先处理视频流,再处理音频流,最后合并。

请教能否让批处理“同时”,而不是队列,处理视频流和音频流??

具体命令是这样的:

代码:

setlocal EnableDelayedExpansion
set Format=*.avi *.mkv *.mp4 *.mpg *.vob *.wmv
set ffmpeg=%CD%\Binaries\ffmpeg_4.1.3.exe
set neroaac=%CD%\Binaries\NeroAACEnc.exe
set x265=%CD%\Binaries\x265_Yuuki_3.0.2.23_10Bit.exe
set mediainfo=%CD%\Binaries\MediaInfo_18.05.exe

for /f "delims=" %%a in ('dir %Format% /b') do (
  for /f %%A in ('%mediainfo% --Output^=Video^;%%AspectRatio%% "%%a"') do (
  if %%A GEQ 1.5 (set WIDTH=16/9) else set WIDTH=4/3)
  for /f %%A in ('%mediainfo% --Output^=Video^;%%FrameCount%% "%%a"') do (
  set FRAMESCOUNT=%%A)
%ffmpeg% -y -v 16 -i "%%a" -an -pix_fmt yuv420p -vf zscale=w=!WIDTH!*468:h=468:f=spline36 -strict -1 -f yuv4mpegpipe - | %x265% --y4m -D 10 --frames !FRAMESCOUNT! --stylish --sar 1 --crf 26 --preset slower --tune lp++ --keyint 75 -o "%Temp%\%%~na.hevc" -
%ffmpeg% -y -v 16 -i "%%a" -vn -ar 44100 -async 1 -f wav pipe:|%neroaac% -ignorelength -hev2 -br 32000 -if - -of "%Temp%\%%~na.m4a"
%ffmpeg% -y -v 16 -i "%Temp%\%%~na.hevc" -i "%Temp%\%%~na.m4a" -map 0:v -map 1:a -map_metadata -1 -map_chapters -1 -c copy "Done\%%~na.mp4"
del /q "%Temp%\%%~na.hevc"
del /q "%Temp%\%%~na.m4a"
move "%%a%" Original
)

请教一下应该如何改造这个脚本,目的是实现同时压音频和视频,然后等待视频压制完成后,用ffmpeg合成一个mp4。因为压视频的时候,CPU跑不满,浪费了压音频的时间。

princenigma 2019-10-02 13:09:39

用 start 或其他第三方工具另起进程

szkent 2019-10-02 14:09:51

用 start 调用另一个bat

ASBai 2019-10-03 00:17:06

LZ 没说平台,MSW 的话就是楼上说的 start,linux 的话 nohup。

但是我感觉关键问题在于等待两个并行任务完成并执行音视频合并这块怎么处理。这说白了是个最简单初级的 MR 算法问题。

princenigma 2019-10-03 09:11:43

批处理有wait process end 之类的工具

midi 2019-10-05 10:09:39

我正好也有相同需求。最后是如下实现的:

1. 创建一个批处理文件
2. 添加:
start call "batch1.bat"
start call "batch2.bat"
3. 保存并运行

结果就是,一共打开两个命令行窗口,这两个窗口一个Hub,一个是client。

MacOS 2019-10-05 13:52:22

引用:

作者: ASBai (文章 17437793)
LZ 没说平台,MSW 的话就是楼上说的 start,linux 的话 nohup。

但是我感觉关键问题在于等待两个并行任务完成并执行音视频合并这块怎么处理。这说白了是个最简单初级的 MR 算法问题。

不严谨的话,由视频作为主进程判断,执行完后检查音频完成没有,没完成就循环等待,可能会有点时间浪费

林展扬 2019-10-10 21:23:48

搞不定,求大佬指点一下~

midi 2019-10-11 11:16:58

1 个附件
对LZ的脚本,看不太懂:blush; 这里说说俺的思路,仅供参考:

可以创建三个批处理,一个处理视频,一个处理音频。第三个让两个批处理“同时”运行,等视频处理完后,将两者再合并。

视频的(batch1.bat):
代码:

echo "video started"
ffmpeg -i video.mp4 -b 1000000 output1.mp4
echo "video ended"
exit 0

音频的(batch2.bat):
代码:

echo "audio started"
ffmpeg -i audio.mp4 -b 1000000 output2.mp4
echo "audio ended"
exit 0

合并的批处理(batch.bat):
代码:

echo "start calling audio batch..."
start call batch2.bat
echo "start calling video batch and wait it to finish..."
start /wait call batch1.bat
echo "both batch 1 and batch 2 have finished. merging two files..."
ffmpeg -i video.mp4 -i audio.mp4 -filter_complex hstack output.mp4
echo "Job done!"

效果见附件Gif(由于太长,去掉了些视频)。

林展扬 2019-10-11 12:32:17

引用:

作者: midi (文章 17443451)
对LZ的脚本,看不太懂:blush; 这里说说俺的思路,仅供参考:

可以创建三个批处理,一个处理视频,一个处理音频。第三个让两个批处理“同时”运行,等视频处理完后,将两者再合并。

视频的(batch1.bat):
[CODE]
[FONT="Courier New"]echo "vid......

我试试看~多谢热心的兄弟。
:cool:

ebirdcn 2019-10-11 12:37:00

uibot

ASBai 2019-10-12 01:17:56

引用:

作者: midi (文章 17443451)
对LZ的脚本,看不太懂:blush; 这里说说俺的思路,仅供参考:

可以创建三个批处理,一个处理视频,一个处理音频。第三个让两个批处理“同时”运行,等视频处理完后,将两者再合并。

视频的(batch1.bat):
[CODE]
[FONT="Courier New"]echo "vid......

感觉可行,前提是保证 batch1 永远在 batch2 之后完成。由于视频编码运算量一般远高于音频,所以大部分情况是应该可以保证的。但考虑到多核编码器和 CPU 调度等影响,最好再降低一下 batch1 的优先级,确保它是最后完成的。

更保险的是在 batch.bat 最后合并音视频前加一个循环等待 batch2 音频文件 ready 的检查。可以在 batch2 的最后 move 或 rename 音频文件,然后在 batch 里循环检查文件存在性。

midi 2019-10-12 08:57:53

引用:

作者: ASBai (文章 17443973)
感觉可行,前提是保证 batch1 永远在 batch2 之后完成。由于视频编码运算量一般远高于音频,所以大部分情况是应该可以保证的。但考虑到多核编码器和 CPU 调度等影响,最好再降低一下 batch1 的优先级,确保它是最后完成的。更保险的是在 batch.bat 最后合并音视频前加一个循环等待 batch2 音频......

说得在理:D。考虑到batch1有可能在batch2之前完成的情况,参考下面的步骤(已测试可行):
1)在batch2里添加一条,完成后,生成一个标志文件(比如audio_ended.txt)。也就是添加:
代码:

echo.>"audio_ended.txt"
2)合并的批处理(batch.bat)中,添加循环语句。循环次数足够大,检查audio_ended.txt是否存在。不存在的话,等待2秒(可以自己定义)。存在的话,就开始合并:
代码:


:: Delete previous files
Del *_ended.txt /Q

:: Variables
:: LookForFile="C:\Path\To\File.txt"
SET LookForFile="audio_ended.txt"

echo start calling audio batch...
start call batch2.bat
echo start calling video batch and wait it to finish...
start /wait call batch1.bat

:: For Loop: ensure another batch is also finished
FOR /L %%i IN (1,1,300000) DO (
      If Exist %LookForFile% (
        echo merging those files
        ffmpeg -i video.mp4 -i audio.mp4 -filter_complex hstack output.mp4
        echo "Job Done!"
        Pause
        Exit

    ) Else (
        timeout /t 2
    )
)


hnlyzhd 2019-10-12 09:27:28

引用:

作者: midi (文章 17444043)
说得在理:D。考虑到batch1有可能在batch2之前完成的情况,参考下面的步骤(已测试可行):
1)在batch2里添加一条,完成后,生成一个标志文件(比如audio_ended.txt)。也就是添加:
[CODE]
[FONT="Courier New"]echo.>"audio_ended.txt"[/FONT...

不要用FOR循环,用GOTO循环就可以了。

:_WaitAudio
if not exist %LookForFile% (
timeout /t 2
goto _WaitAudio)

:_DoJob
echo merging those files
ffmpeg -i video.mp4 -i audio.mp4 -filter_complex hstack output.mp4

ASBai 2019-10-12 23:14:25

引用:

作者: midi (文章 17444043)
说得在理:D。考虑到batch1有可能在batch2之前完成的情况,参考下面的步骤(已测试可行):
1)在batch2里添加一条,完成后,生成一个标志文件(比如audio_ended.txt)。也就是添加:
[CODE]
[FONT="Courier New"]echo.>"audi......

那么你 batch2 里的第一句应该是先删除 audio_ended.txt,防止上一次残留物影响这次判断 :)


所有时间均为北京时间, 现在的时间是 12:54:34.

本论坛带宽由迅通网络提供
SSL证书由TrustAsia提供

Copyright © 2000 - 2019 ClassiClub Forum All Rights Reserved.
粤ICP备09123456号