标题: [文件操作] 批处理怎样在文件夹后追加文件夹内视频总时长? [打印本页]
作者: qd2024 时间: 2024-1-27 21:05 标题: 批处理怎样在文件夹后追加文件夹内视频总时长?
实现 在文件夹文件名后插入文件夹内视频文件总时长,
以分钟形式表示,如果秒数不为0,则在分钟上+1.
如,文件夹内视频总时和1小时5分1秒,计算后标记66,再分钟前后分别加“【” “】”
如使用第三方软件,需要在BAT里设置文件路径,如使用ffmpeg,要在bat标记路径,如D:\tool\ffmpeg.exe
链接:https://pan.baidu.com/s/1l0uoyc616V4REeioKOzc6w?pwd=qcef
提取码:qcef
--来自百度网盘超级会员V10的分享
谢谢
作者: newswan 时间: 2024-1-27 22:30
没有处理秒
将文件夹拖到bat上,显示正确,去掉 ren 前的 echo- @echo off
- SETLOCAL ENABLEDELAYEDEXPANSION
-
- set folder=%1
-
- pushd %folder%
- set/a time=0
- for /f "usebackq" %%a in (` dir /b *.mkv `) do (
- for /f "usebackq tokens=2,3 delims=: " %%i in (` "ffprobe.exe %%a 2>&1 | findstr Duration" `) do (
- set /a time+=%%i*60+%%j
- )
- )
- popd
-
- echo ren %folder% %folder%[%time%]
-
- pause
- exit/b
复制代码
作者: qd2024 时间: 2024-1-27 23:35
本帖最后由 qd2024 于 2024-1-27 23:44 编辑
回复 2# newswan
感谢 视频扩展名改为mp4 测试没有成功 帮忙看看
作者: newswan 时间: 2024-1-28 10:15
回复 3# qd2024
将文件夹拖到bat上
或者 手动设置 folder 变量
作者: qd2024 时间: 2024-1-28 10:54
回复 4# newswan
对的 就是拖文件夹到 BAT上 出现这样提示
作者: 77七 时间: 2024-1-28 13:36
这个不能用吗
作者: czjt1234 时间: 2024-1-28 15:39
批处理保存为ansi编码呢
作者: qd2024 时间: 2024-1-28 16:15
回复 7# czjt1234
试了 提示一样的
作者: qd2024 时间: 2024-1-28 16:16
回复 6# 77七
我试试
作者: newswan 时间: 2024-1-28 18:02
路径有空格?- @echo off
- SETLOCAL ENABLEDELAYEDEXPANSION
-
- set folder=%~1
-
- set ffPath=D:\Program Files
-
- pushd "%folder%"
-
- set/a time=0
- for /f "usebackq" %%a in (` dir /b *.mkv `) do (
- for /f "usebackq tokens=2,3 delims=: " %%i in (` ""%ffpath%\ffprobe.exe" %%a 2>&1 | findstr Duration" `) do (
- set /a time+=%%i*60+%%j+1
- )
- )
- echo %time%
-
- popd
-
- echo ren "%folder%" "%folder%[%time%]"
-
- pause
- exit/b
复制代码
作者: newswan 时间: 2024-1-28 18:32
ai 给了一个直接获取时长的方法- ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 input.mp4
- 30.024000
复制代码
作者: ppll2030 时间: 2024-1-28 19:16
本帖最后由 ppll2030 于 2024-1-28 22:17 编辑
二楼的时间好像有问题,我段位低,理解不了。
所以用Batcher大大的分段截取代码,再组合一下。
楼主可以试试。- @echo off
- setlocal enabledelayedexpansion
- set folder=%~1
- set ffpath=H:\共享影视\Download\FFmpeg\ffmpeg.exe
- pushd "%folder%"
- for /f "delims=" %%i in ('dir /b /s /a-d *.avi *.mkv *.mp4 *.rmvb *.wmv') do (
- for /f "tokens=2 delims=, " %%a in ('%ffpath% -i "%%i" 2^>^&1 ^| find "Duration:"') do set "str=%%a"
- set str=!str:~0,-3!
- for /f "tokens=1-3 delims=:" %%x in ("!str!") do (
- set "hh=%%x"
- set "mm=%%y"
- set "ss=%%z"
- set /a minutes=1!hh!*60-6000
- set /a minutes+=1!mm!-100
- if !ss! neq 0 (set /a minutes+=1)
- )
- set /a Totalduration+=!minutes!
- )
- popd
- echo ren "%~1" "%~n1【!Totalduration!】"
- pause
复制代码
作者: newswan 时间: 2024-1-28 19:50
文件名可能有空格- @echo off
- SETLOCAL ENABLEDELAYEDEXPANSION
-
- set folder=%~1
-
- set ffPath=D:\Program Files
-
- pushd "%folder%"
-
- set/a time=0
- for /f "usebackq tokens=* delims=" %%a in (` dir /b *.mkv `) do (
- for /f "usebackq tokens=2,3 delims=: " %%i in (` ""%ffpath%\ffprobe.exe" "%%a" 2>&1 | findstr Duration" `) do (
- set /a time+=%%i*60+%%j+1
- )
- )
- echo %time%
-
- popd
-
- echo ren "%folder%" "%folder%[%time%]"
-
- pause
- exit/b
复制代码
作者: qd2024 时间: 2024-1-28 20:24
回复 10# newswan
提示如下图,帮我再看看,我上传例子文件到百度云盘了,谢谢。
链接:https://pan.baidu.com/s/1mPzdlyhFy4UY1l6OECw7IA?pwd=nro4
提取码:nro4
--来自百度网盘超级会员V10的分享
作者: qd2024 时间: 2024-1-28 20:24
回复 12# ppll2030
提示如下图,帮我再看看,我上传例子文件到百度云盘了,谢谢。
链接:https://pan.baidu.com/s/1mPzdlyhFy4UY1l6OECw7IA?pwd=nro4
提取码:nro4
--来自百度网盘超级会员V10的分享
作者: qd2024 时间: 2024-1-28 20:25
回复 13# newswan
提示如下图,帮我再看看,我上传例子文件到百度云盘了,谢谢。
链接:https://pan.baidu.com/s/1mPzdlyhFy4UY1l6OECw7IA?pwd=nro4
提取码:nro4
--来自百度网盘超级会员V10的分享
作者: ppll2030 时间: 2024-1-28 20:34
本帖最后由 ppll2030 于 2024-1-28 22:26 编辑
回复 15# qd2024
毒盘非会员,无法下载。
复制代码保存为bat文件,然后视频文件夹拖拽到bat文件上就可以了。
脚本需要第三方ffmpeg.exe。
第三行的ffmpeg路径请修改为自己的实际路径。
提示找不到文件,可能视频后缀名不对。已添加多个常用视频
照搬二楼的码。去除echo,无法更名的bug,12楼的已更正
作者: newswan 时间: 2024-1-28 20:44
回复 16# qd2024
不好意思,没有实际运行,忘记了 ren 不能用全路径
用了两种方法- @echo off
- SETLOCAL ENABLEDELAYEDEXPANSION
-
- set ffPath=D:\Program Files
-
- set folderPath=%~dp1
- set folderName=%~nx1
-
- pushd "%folderPath%\%folderName%"
-
- set/a time=0
- for /f "usebackq tokens=* delims=" %%a in (` dir /b *.mkv `) do (
- for /f "usebackq tokens=1,2 delims=." %%i in (`" "%ffpath%\ffprobe.exe" -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 "%%a" "`) do (
- set/a time+=%%i
- )
- )
- set/a time/=60
- echo %time%
-
- set/a time=0
- for /f "usebackq tokens=* delims=" %%a in (` dir /b *.mkv `) do (
- for /f "usebackq tokens=2,3,4 delims=:. " %%i in (` ""%ffpath%\ffprobe.exe" "%%a" 2>&1 | findstr Duration" `) do (
- set /a time+=%%i*3600+%%j*60+%%k
- )
- )
- set/a time/=60
- echo %time%
-
- popd
-
- pushd "%folderPath%"
- echo ren "%folderName%" "%folderName%[%time%]"
- popd
-
- pause
- exit/b
复制代码
作者: newswan 时间: 2024-1-28 20:46
没下载你的文件,太大,用自己的文件测试了可行
作者: buyiyang 时间: 2024-1-28 20:46
- @if(0)==(0) @echo off
- cd /d "%~dp0"
- for /d %%d in (*) do (
- pushd "%%d"
- for /f "delims=" %%i in ('dir /b /a-d "*.mp4"^|cscript /e:jscript /Nologo "%~f0"') do (
- popd
- ren "%%d" "%%d【%%i】"
- )
- )
- pause&exit
- @end
- objPlayer=new ActiveXObject("WMPlayer.OCX"),ws=WSH.stdin,durationInSeconds=0;
- while (!ws.atendofstream) {
- var filePath = ws.readline();
- var objMedia = objPlayer.newMedia(filePath);
- durationInSeconds += objMedia.duration
- }
- WScript.Echo(Math.ceil(durationInSeconds/60));
复制代码
作者: qd2024 时间: 2024-1-28 21:59
回复 18# newswan
我把代码调成这样- @echo off
- SETLOCAL ENABLEDELAYEDEXPANSION
-
- set ffPath=D:\Program Files
-
- set folderPath=%~dp1
- set folderName=%~nx1
-
- pushd "%folderPath%\%folderName%"
-
-
- set/a time=0
- for /f "usebackq tokens=* delims=" %%a in (` dir /b *.mp4 `) do (
- for /f "usebackq tokens=2,3,4 delims=:. " %%i in (` ""%ffpath%\ffprobe.exe" "%%a" 2>&1 | findstr Duration" `) do (
- set /a time+=%%i*3600+%%j*60+%%k
- )
- )
- set/a time/=60
- echo %time%
-
- popd
-
- pushd "%folderPath%"
- ren "%folderName%" "%folderName%【%time%】"
- popd
-
- pause
- exit/b
复制代码
把文件夹拖到BAT上 ,提示如下图,再帮我看盾是什么原因,别一段提示找不文件
作者: newswan 时间: 2024-1-28 23:59
回复 15# qd2024
以0开头的数字- @echo off
- SETLOCAL ENABLEDELAYEDEXPANSION
- chcp 936
-
- set ffPath=D:\Program Files
-
- set folderPath=%~dp1
- set folderName=%~nx1
-
-
- pushd "%folderPath%\%folderName%"
-
- echo "--1--"
- set time=0
- for /f "usebackq tokens=* delims=" %%a in (` dir /b *.mp4 `) do (
- for /f "usebackq" %%i in (`" "%ffpath%\ffprobe.exe" -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 "%%a" "`) do (
- set time=!time! + %%i
- )
- )
- for /f "usebackq" %%a in (` powershell -command " [math]::Ceiling( (%time%) / 60 ) " `) do (
- set time=%%a
- )
- echo %time%
-
- echo "--2--"
- set/a time=0
- for /f "usebackq tokens=* delims=" %%a in (` dir /b *.mp4 `) do (
- for /f "usebackq tokens=1,2 delims=." %%i in (`" "%ffpath%\ffprobe.exe" -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 "%%a" "`) do (
- set/a time+=%%i
- )
- )
- set/a time/=60
- set/a q=%time%%60
- if %q% gtr 0 (set/a time+=1)
- echo %time%
-
- echo "--3--"
- set/a time=0
- for /f "usebackq tokens=* delims=" %%a in (` dir /b *.mp4 `) do (
- for /f "usebackq tokens=2,3,4 delims=:. " %%i in (` ""%ffpath%\ffprobe.exe" "%%a" 2>&1 | findstr Duration" `) do (
- set/a time+=1%%i*3600+1%%j*60+1%%k-100*3600-100*60-100
- )
- )
- set/a time/=60
- set/a q=%time%%60
- if %q% gtr 0 (set/a time+=1)
- echo %time%
-
- popd
-
- pushd "%folderPath%"
- echo ren "%folderName%" "%folderName%[%time%]"
- popd
-
- pause
- exit/b
复制代码
作者: qd2024 时间: 2024-1-29 12:09
回复 22# newswan
成功 谢谢 有没有可能实际 对二级目录的批量处理 就是拖一个文件夹,这个文件夹根下没有视频文件,这个文件夹下有多个文件夹内包含视频文件,对这些文件夹进行追加时长处理
作者: newswan 时间: 2024-1-29 12:32
回复 23# qd2024
这个涉及到一个问题,仅本文件夹?包含子文件夹
作者: qd2024 时间: 2024-1-29 14:20
回复 24# newswan
这样 被拖到BAT上的文件夹A里 不包含 视频文件 A下有B C D等文件夹 B C D等文件夹内有视频文件 ,
A拖到BAT上后,统计BCD文件时长,统计后变为B【XX】 C【XX】 D【XX】
如果A能追加上其下所有子目录的时长更好。
不知道有没有表达明白,谢谢。
作者: newswan 时间: 2024-1-29 17:36
明白,还有个问题,上面是每个文件夹时长总和去整。不是每个视频时长去整再想加
作者: aloha20200628 时间: 2024-1-29 17:38
本帖最后由 aloha20200628 于 2024-1-29 20:10 编辑
回复 25# qd2024
看楼主用数学题轮训各位热心解答者,也跟一帖。
代码说明:
一。获取dir简报结果至少须用 "delims=" 禁止系统分隔符(,; =),须用 /s 获取全路径文件名
二。用双引号包裹命令表达式,减少打理转义符的麻烦
三。ffprobe筛选时长的参数表达式虽然很多,但其输出效率之差可忽略,选择最轻量化代码即可
四。本帖要求时长误差是分钟级,故可免去调用外部浮点运算功能
以下代码可存为test.bat,将一级目录拖给它即可,完成一级目录及其子目录的更名》源目录名【时长】。- @echo off
- if "%~1"=="" (exit/b) else (setlocal enabledelayedexpansion)
- set fpb="C:\ffmpeg\bin\ffprobe.exe"
- for /f "delims=" %%D in (' dir /b/s/ad "%~1" ') do (
- for /f "delims=" %%F in (' dir /b/s/a-d "%%~D\*.mp4" ') do (
- for /f "tokens=1-4 delims=:. " %%1 in (' "%fpb% "%%~F" 2>&1 | findstr /ic:"Duration:" " ') do (
- set/a "m+=%%2*60+%%3,s+=%%4">nul 2>nul
- )
- )
- set/a "ms=s/60,sm=s%%60,m+=ms">nul 2>nul
- if !sm! neq 0 (set/a m+=1)
- ren "%%~D" "%%~nxD【!m!】" & set/a "mm+=m,m=s=0"
- )
- ren "%~1" "%~nx1【!mm!】"
- endlocal&exit/b
复制代码
作者: newswan 时间: 2024-1-29 18:01
回复 27# aloha20200628
各人习惯,不调用 find 比较好
或者用 vbs 计算也好,powershell 慢,但是我对 vbs 不太明白。
作者: aloha20200628 时间: 2024-1-29 19:56
给一个不调用ffprobe.exe的bat+jscript混编版本,直接调用windows系统内置的fso功能获取媒体文件属性(如时长),与用ffprobe.exe/mediainfo.exe等外部方法对比可明显提速(尤其是大目录操作),因批处理脚本调用后者是逐个文件处理,而前者能一次性批量处理。
以下代码可存为test.bat,将一级目录拖给它即可,完成一级目录及其子目录的更名》源目录名【时长】。- @set @v=1 /*
- @echo off
- if "%~1"=="" (exit/b) else (setlocal enabledelayedexpansion)
- (for /f "delims=" %%D in (' dir /b/s/ad "%~1" ') do (
- for /f %%v in (' " dir/b/s/a-d "%%~D\*.mp4"|cscript /e:jscript "%~f0" " ') do (set "m=%%v")
- set/a "mm+=!m!" & ren "%%~D" "%%~nxD【!m!】"
- )
- ren "%~1" "%~nx1【!mm!】" & endlocal & exit/b) 2>nul
- */
- m = s = ms = sm = 0, ws = WSH.stdin, sa = WSH.createobject('shell.application');
- while (!ws.atendofstream) {
- F = ws.readline(); i = F.lastIndexOf('\\'), pF = F.substr(0,i+1), nF = F.substr(i+1);
- ns = sa.namespace(pF), pn = ns.parsename(nF); d = ns.getdetailsof(pn,27).split(':');
- m += ~~d[0]*60 + ~~d[1]; s += ~~d[2];
- }
- WSH.echo(m+=Math.ceil(s/60));
复制代码
作者: qd2024 时间: 2024-1-29 20:02
回复 26# newswan
这样 被拖到BAT上的文件夹A里 不包含 视频文件 A下有B C D等文件夹 B C D等文件夹内有视频文件 ,
A拖到BAT上后,统计BCD文件时长,统计后变为B【XX】 C【XX】 D【XX】
如果A能追加上其下所有子目录的时长更好。
不知道有没有表达明白,谢谢。
就是说 B C D……只计算自己文件夹下的视频的时间和,A是把所有子目录的所有视频时间和标记出来
作者: newswan 时间: 2024-1-29 20:13
回复 29# aloha20200628
支持哪些媒体文件?
作者: aloha20200628 时间: 2024-1-29 20:24
回复 31# newswan
类同资源管理器各种媒体文件文件属性列表中的时长。可修改29楼代码中的*.mp4(扩展名),验证结果...
作者: qd2024 时间: 2024-1-29 22:55
本帖最后由 qd2024 于 2024-1-29 23:04 编辑
回复 31# newswan
常见 MP4 MOV WMV FLV AVI 刚刚加了MP3文件测试成功 感谢
作者: qd2024 时间: 2024-1-30 07:49
回复 27# aloha20200628
谢谢 MP4 测试成功
我尝试加上MP3的扩展名没有成功,
能否让代码支持更多这视频格式,包括音频mp3
作者: ppll2030 时间: 2024-1-30 10:02
回复 newswan
这样 被拖到BAT上的文件夹A里 不包含 视频文件 A下有B C D等文件夹 B C D等文件 ...
qd2024 发表于 2024-1-29 20:02
这个题目有点意思,我也来练练手,欢迎测试。
1、增加了同时识别多种音频视频格式。
2、增加了文件个数统计。
3、需第3方FFmpeg,比系统自带识别格式更多。
4、避开08 09无效数字的bug- @echo off
- setlocal enabledelayedexpansion
- set folder=%~1
- REM 请修改自己的实际路径
- set ffpath=D:\FFmpeg\ffmpeg.exe
-
- for /f "delims=" %%f in ('dir /b /ad "%~1"') do (
- set /a foldermin=0
- set /a n=0
- pushd "%~1"
- REM 可添加多种格式,适用于一个文件夹内有多种格式的视频。
- for /f "delims=" %%i in ('dir /b /s /a-d "%%f" ^| findstr /i ".mp3$ .mp4$ .avi$ .mkv$ .rmvb$ .wmv$ .flac$ .flv$"') do (
- for /f "tokens=2 delims=, " %%a in ('%ffpath% -i "%%i" 2^>^&1 ^| findstr "Duration:"') do set "str=%%a"
- set str=!str:~0,-3!
- for /f "tokens=1-3 delims=:" %%x in ("!str!") do (
- set "hh=%%x"
- set "mm=%%y"
- set "ss=%%z"
- set /a minutes=1!hh!*60-6000
- set /a minutes+=1!mm!-100
- if !ss! neq 0 (set /a minutes+=1)
- )
- ::echo !str! !minutes!
- set /a foldermin+=!minutes!
- set /a n+=1
- )
- REM 执行更名,请去除 echo
- echo ren "%%~f" "%%~nf【共!n!个视频,总时长!foldermin!分钟】"
- set /a Totalmin+=!foldermin!
- set /a Totaln+=!n!
- popd
- )
- REM 执行更名,请去除 echo
- echo ren "%~1" "%~n1【共!Totaln!个视频,总时长!Totalmin!分钟】"
- pause
复制代码
作者: aloha20200628 时间: 2024-1-30 10:16
回复 34# qd2024
27楼或29楼代码中的第5行》修改 *.mp4 为 *.mp? 即可包括 mp4/mp3 音视频文件
如果子目录中全是常见类型的音视频文件(mp4/mkv/avi/wmv/vob/ts/mpg/mp3/flac/wav/...),可修改为 *.* 通配符涵盖所有文件。
作者: newswan 时间: 2024-1-30 10:34
支持多级文件夹- @echo off
- setlocal ENABLEDELAYEDEXPANSION
- chcp 936
-
- set ffPath=D:\Program Files
-
- set folderPath=%~dp1
- set folderName=%~nx1
-
- pushd "%folderPath%"
-
- call :C_get-Duration "%folderName%" time
-
- popd
-
- pause
- exit/b
-
- Usage: %0 <folder> <return:duration>
- :C_get-Duration
- setlocal
-
- set folderName=%~1
- pushd "%folderName%"
- set/a level+=1
-
- echo,
- echo ---- %level% %CD% ----
-
- set timeSubfolderAll=0
- for /f "usebackq tokens=* delims=" %%a in (` 2^>nul dir /b /ad . `) do (
- echo "%%a"
- if not "%%a" == "" (
- call :C_get-Duration "%%a" timeSubfolder
- set/a timeSubfolderAll+=!timeSubfolder!
- )
- )
-
- echo "--1--"
- set time=0
- for /f "usebackq tokens=* delims=" %%a in (` 2^>nul dir /b *.mp4 `) do (
- for /f "usebackq" %%i in (`" "%ffpath%\ffprobe.exe" -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 "%%a" "`) do (
- set time=!time! + %%i
- )
- )
- for /f "usebackq" %%a in (` powershell -command " [math]::Ceiling( (%time%) / 60 ) " `) do (
- set time=%%a
- )
- echo %time%
-
- echo "--2--"
- set/a time=0
- for /f "usebackq tokens=* delims=" %%a in (` 2^>nul dir /b *.mp4 `) do (
- for /f "usebackq tokens=1,2 delims=." %%i in (`" "%ffpath%\ffprobe.exe" -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 "%%a" "`) do (
- set/a time+=%%i
- )
- )
- set/a time/=60
- set/a q=%time%%60
- if %q% gtr 0 (set/a time+=1)
- echo %time%
-
- echo "--3--"
- set/a time=0
- for /f "usebackq tokens=* delims=" %%a in (` 2^>nul dir /b *.mp4 `) do (
- for /f "usebackq tokens=2,3,4 delims=:. " %%i in (` ""%ffpath%\ffprobe.exe" "%%a" 2>&1 | findstr Duration" `) do (
- set/a time+=1%%i*3600+1%%j*60+1%%k-100*3600-100*60-100
- )
- )
- set/a time/=60
- set/a q=%time%%60
- if %q% gtr 0 (set/a time+=1)
- echo %time%
- set/a time+=%timeSubfolderAll%
-
- popd
- set/a level-=1
- echo,
- echo ---- %level% %CD% ----
- echo ren "%folderName%" "%folderName%[%time%]"
- echo,
- (
- endlocal
- set %2=%time%
- )
-
- goto :eof
复制代码
作者: newswan 时间: 2024-1-30 10:37
第二种比较合适这个需求
欢迎光临 批处理之家 (http://bbs.bathome.net/) |
Powered by Discuz! 7.2 |