标题: [文件操作] 批处理如何实现:7天内随机播放不重复的音乐? [打印本页]
作者: yanni_enya 时间: 2023-12-11 14:18 标题: 批处理如何实现:7天内随机播放不重复的音乐?
如题所示:每天固定时段在同一个文件夹内随机播放一个音乐,7天内播放过的音乐不再播放,7天后一个轮回。
我自己在网上找了一段大神的批处理,能实现每次都随机播放,但避免不了重复,代码如下:- @echo off&color a&setlocal enabledelayedexpansion
- for %%a in ("D:\jhrw\现用音乐\music\*.bat") do set /a n+=1
- set /a m=%random%%%%n%
- if %m% equ 0 set m=%n%
- for %%a in ("D:\jhrw\现用音乐\music\*.bat") do (
- set /a counter+=1
- if !counter! equ %m% start %%a
- )
复制代码
作者: _avatar_ 时间: 2023-12-11 15:03
不想不重复,就得记录播放过的歌曲
作者: yanni_enya 时间: 2023-12-11 16:06
用批处理怎么实现?
作者: 77七 时间: 2023-12-11 17:18
本帖最后由 77七 于 2023-12-13 17:43 编辑
- @echo off
- rem 1.批处理保存为utf-8编码格式;
- rem 2.播放软件:MPV (https://mpv.io/);音量设定:nircmd (http://bcn.bathome.net/tool/nirsoft,2.86/nircmd.exe);均需添加到电脑环境变量。
- chcp 65001 >nul
- set "folder=D:\mp3"
- set /a k=m=0,e=(d=次数=7)*(n=数量=1)
- if not exist "%folder%\list.txt" (
- cd.>"%folder%\list.txt"
- )
-
- :1
- setlocal
- for /f "useback delims=" %%a in ("%folder%\list.txt") do (
- set _"%%a"=1
- set /a k+=1
- )
- if %k% geq %e% (
- cd.>"%folder%\list.txt"
- endlocal
- goto :1
- )
- for /f "delims=" %%i in ('dir /b /a-d "%folder%\*.mp3" "%folder%\*.flac"') do (
- if not defined _"%%i" (
- call set #%%random%%=%%i
- set /a m+=1
- )
- )
- if %m% lss %n% (
- cd.>"%folder%\list.txt"
- endlocal
- goto :1
- )
- for /f "tokens=1* delims==" %%a in ('set #') do (
- echo 播放 [%%b]
- nircmd mutesysvolume 0
- nircmd setsysvolume 30000
- rem 自行设置播放器
- mpv --window-minimized "%folder%\%%b"
- nircmd setsysvolume 0
- nircmd mutesysvolume 1
- >>"%folder%\list.txt" echo %%b
- set /a n-=1,1/n 2>nul || exit
- )
复制代码
作者: ShowCode 时间: 2023-12-11 17:41
回复 1# yanni_enya
试试这两个:
http://bbs.bathome.net/thread-67358-1-1.html
http://bbs.bathome.net/thread-56468-1-1.html
作者: _avatar_ 时间: 2023-12-11 23:38
我试着写了一个,脚本的不重复周期通过 loop 变量控制,默认周期为七天。
每天的运行次数不限,只要你的歌库数量足够。
调用的播放器由系统设置的默认支持的播放器决定。
默认支持的歌曲类型: flac / mp3 / wav / ape , 其他格式可自行添加。
周期之内如果所有歌曲都被播放过,再次运行会提示 “所有歌曲都已经播放过一遍了”
脚本会设置一个系统环境变量 “playConfig”, 如果与已有系统环境变量冲突,请自行修改!
脚本代码:- @echo off&mode con cols=20 lines=2&color a&setlocal enabledelayedexpansion
-
- set loop=7
- set str=%date:/=%
- set now=%str:~0,8%
- set config=%now%;1;1;0
-
- for /r %%i in (*.flac *.mp3 *.wav *.ape) do set /a total+=1
- echo # 歌曲列表 >list.txt
- dir *.flac *.mp3 *.wav *.ape /s /b >>list.txt
- set /a total+=1
-
- if NOT DEFINED playConfig (
- setx /m playConfig "%config%" >nul
- set playConfig=%config%
- )
-
- for /f "eol=# delims=; tokens=1,2,3,4" %%i in ("%playConfig%") do (
- set d=%%i
- set c=%%k
- set /a t=%%j
- set nums=%%l
- if "%%i" neq "%now%" (
- set /a t=%%j+1
- set d=%now%
- )
- )
-
- :rand
- set /a randNum=%random%%%!total!
-
- :start
- if !c! geq !total! echo 所有歌曲都已经播放过一遍啦! & pause>nul & goto :eof
- for %%i in (!nums!) do if %%i == %randNum% goto rand
- set /a c+=1
- if !t! leq %loop% set config=!d!;!t!;!c!;!nums!
- setx /m playConfig "%config%,%randNum%" >nul
- for /f "skip=%randNum% delims=" %%i in (list.txt) do start "" "%%i" & goto :eof
复制代码
作者: Five66 时间: 2023-12-11 23:50
这样行不,随机到的音乐移动到“已播放”文件里后才播放,当“已播放”文件里的音乐文件数量大于一定数量(默认7)时移动回去- @echo off
-
- set times=7
- set "ph=D:\jhrw\现用音乐\music"
-
- if not exist "%ph%\已播放" md "%ph%\已播放"
- set n=0
- for %%a in ("%ph%\已播放\*") do set /a n+=1
- if %n% gtr %times% move "%ph%\已播放\*" "%ph%\"
-
- for %%a in ("%ph%\*.flac" "%ph%\*.mp3" "%ph%\*.ogg") do set /a m+=1
- if not defined m (echo no file to play&pause&exit/b)
- set /a r=%random%%%%m%
- if %r% equ 0 set r=%m%
- for %%a in ("%ph%\*.flac" "%ph%\*.mp3" "%ph%\*.ogg") do (
- set /a counter+=1
- for /f %%_ in ('echo %%counter%%') do (
- if %%_ equ %r% (
- move "%%~fa" "%ph%\已播放\" && start "%ph%\已播放\%%~nxa"
- goto :end
- )
- )
- )
-
- :end
- pause
复制代码
作者: yanni_enya 时间: 2023-12-13 16:15
回复 4# 77七
您的脚本我试了一下:一闪而过!
我把我的使用环境再说的具体一些,以下内容是已经实现的:电脑默认静音,每次播放前会自动取消静音并设置音量大小,歌曲播放完后自动关闭播放器进程,电脑自动设置静音。
为了达到这个效果,我给每首歌曲在D:\jhrw\现用音乐\music下都设置了与歌曲名相同的批处理文件(这个批处理用来实现解除静音、设置音量,播歌曲,并在播放完后自动关闭进程和自动加静音)。而随机播放音乐的批处理放在 D:\jhrw\晨乐 , 执行时实际是随机打开了D:\jhrw\现用音乐\music下歌曲同名的批处理。
作者: yanni_enya 时间: 2023-12-13 16:19
回复 6# _avatar_
您给的脚本可以用,但是与我的使用环境有出入:
我给每首歌曲在D:\jhrw\现用音乐\music下都设置了与歌曲名相同的批处理文件(这个批处理用来实现解除静音、设置音量,播歌曲,并在播放完后自动关闭进程和自动加静音)。而随机播放音乐的批处理放在 D:\jhrw\晨乐 , 执行时实际是随机打开了D:\jhrw\现用音乐\music下歌曲同名的批处理。
而且您的脚本有人为的判断,我想要7天到了自动重新开始在歌曲里再次随机播放歌曲,新的7天仍然不重复即可。
作者: yanni_enya 时间: 2023-12-13 16:29
回复 7# Five66
也是个办法,但是运行时一闪而过,我在cmd里看了一下,提示两次:此时不应有%%a。
我想上传图,总是失败,抱歉。
作者: 77七 时间: 2023-12-13 17:43
回复 8# yanni_enya
如果要实现你描述的功能,以我的水平,只会使用第三方命令行工具nircmd 和mpv ,用一个批处理就可完成。(如果每个音频都搭配一个批处理,好像有点失去批处理的魅力了...)
已在4楼更新代码,代码已测试。
作者: idwma 时间: 2023-12-13 18:23
本帖最后由 idwma 于 2023-12-13 18:30 编辑
- @echo off&color a&setlocal enabledelayedexpansion
- for %%a in ("D:\jhrw\现用音乐\music\*.bat.skip") do set /a n+=1
- if n geq 7 (
- for %%a in ("D:\jhrw\现用音乐\music\*.bat.skip") do move "%%i" "%%~dpni"
- )
- set n=
- for %%a in ("D:\jhrw\现用音乐\music\*.bat") do set /a n+=1
- set /a m=%random%%%%n%
- if %m% equ 0 set m=%n%
- for %%a in ("D:\jhrw\现用音乐\music\*.bat") do (
- set /a counter+=1
- if !counter! equ %m% (
- start %%a
- ping -n 2 127.0.0.1 >nul
- move "%%a" "%%a.skip"
- )
- )
复制代码
作者: Batcher 时间: 2023-12-13 20:53
回复 10# yanni_enya
如果需要上传文件,请用使用网盘。
如果需要上传截图,可以找个图床,例如:
http://bbs.bathome.net/thread-60985-1-1.html
作者: yanni_enya 时间: 2023-12-14 09:46
回复 12# idwma
人狠话不多,直接按要求上代码,优秀~
您的代码也是一闪而过,问题仍然是:此处不应有 %%a。
网盘传图片我不会,抱歉没图。
作者: aloha20200628 时间: 2023-12-14 12:30
本帖最后由 aloha20200628 于 2023-12-14 12:39 编辑
假设楼主的曲库不超过8000首,以便批处理脚本可采用最便捷的变量名字典匹配方法;
假设楼主的 D:\jhrw\现用音乐\music\*.bat 其中的文件名不含如 ä、č 等欧洲古典曲目中常见的怪异字符,以免再来回切换系统码页(936/65001)。
代码会在 D:\jhrw\现用音乐\music 目录中创建一个7天有效期记录文件 D:\jhrw\现用音乐\music\list.7,逾期自动清零。- @echo off &setlocal enabledelayedexpansion
- set "7F=D:\jhrw\现用音乐\music\list.7"
- if not exist "!7F!" (cd.>"!7F!") else for /f %%k in ('find /v /c "" ^<"!7F!" ') do if %%k geq 7 (cd.>"!7F!")
- for %%b in ("D:\jhrw\现用音乐\music\*.bat") do (set/a "n+=1" &set "$!n!=%%b")
- :[Loop]
- set/a m=%random%%%%n%+1
- for %%k in (!m!) do (set "mF=!$%%k!")
- find /i "!mF!" "!7F!">nul && goto[Loop]
- echo,!mF!>>"!7F!"
- start "" "!mF!"
- endlocal &exit/b
复制代码
作者: idwma 时间: 2023-12-14 15:20
回复 14# yanni_enya
那就奇怪了,应该到第3行就会出错的,但不应该提示%%a
作者: Five66 时间: 2023-12-15 01:56
回复 10# yanni_enya
啊,7楼代码第19行后面的
start "%ph%\已播放\%%~nxa"
改成
start "" "%ph%\已播放\%%~nxa"
或者其他播放命令
默认音乐文件位置是D:\jhrw\现用音乐\music,不是的话自己修改(7楼代码第4行),还有,得保存为ansi编码的bat
作者: yanni_enya 时间: 2023-12-19 14:20
本帖最后由 yanni_enya 于 2023-12-19 15:19 编辑
回复 15# aloha20200628
能用!! 需要保存成ANSI码,估计之前几位大神的代码也能用,只是我没另存为ANSI码就运行了,实在抱歉啊!
试了半天,大概是这个样子:1、我们在music下能看到已播列表,不晓得在哪生成了一个7次播放都不会重复的待播列表(所谓的7天就是7天内,每天播一首),然后第8次播放就会重新生成一个新的7首曲目不重复播放的列表,依次循环。(music文件夹下生成的已播
列表一旦删除,再次执行代码会随机生成新的待播列表)
2、而且在电脑任意位置执行同一组代码,都是指向同一个随机生成的播放列表!
3、修改播放数字后,生成的播放列表各是各,互不干扰。
明白了这些代码也就好改了,非常感谢诸位大神,膜拜了
作者: aloha20200628 时间: 2023-12-19 18:30
回复 18# yanni_enya
一。15楼代码并没有生成待播列表文件,与曲库乐曲对应的*.bat实际上就相当于待播文件。
二。作为建议,如果你的曲库有上百首,也可将15楼代码第3行中的 geq 7 改为 geq 30,即每月每天不重复播放;如有上千首,甚至可改为 geq 365,即每年每天不重复播放。
三。只要曲目名称或与其对应的*.bat名称不含那些欧洲古典乐曲中常见的 ä、č 等怪异字符,代码运行就不会因其“作祟”。
作者: yanni_enya 时间: 2023-12-20 14:27
回复 19# aloha20200628
您的代码目前我都是整体替换数字7,music文件夹里有多少曲目,我就替换成对应的数字。
geq 后边跟的数字代表对应天数不重复播放歌曲,请问代码中多个7F仅仅是个名称是么? list.7 后边的数字7也可以随意修改么?
作者: aloha20200628 时间: 2023-12-20 15:08
代码中的 7F 是变量名,list.7 是文件名,只有 geq 7 中的 7 才是直接影响重复天数的关键值,作整体替换没问题。
回复 20# yanni_enya
作者: yanni_enya 时间: 2023-12-21 09:58
回复 21# aloha20200628
灰常感谢
作者: yanni_enya 时间: 2023-12-25 16:12
回复 21# aloha20200628
新的需求:music下歌曲越来越多,已播放列表的文件也多起来了,能否给已播放列表里记录的每首歌曲的前边把序号加上,这样看起来一目了然,不然太费眼睛了!
作者: aloha20200628 时间: 2023-12-25 18:08
本帖最后由 aloha20200628 于 2023-12-25 18:09 编辑
回复 23# yanni_enya
新版本在已播放列表文件中加入行首序号。- @echo off &setlocal enabledelayedexpansion
- set "i=0" &set "7F=D:\jhrw\现用音乐\music\list.7"
- if not exist "!7F!" (cd.>"!7F!") else for /f %%k in ('find /v /c "" ^<"!7F!" ') do (set "i=%%k" &if %%k geq 7 (cd.>"!7F!"))
- for %%b in ("D:\jhrw\现用音乐\music\*.bat") do (set/a "n+=1" &set "$!n!=%%b")
- :[Loop]
- set/a m=%random%%%%n%+1
- for %%k in (!m!) do (set "mF=!$%%k!")
- find /i "!mF!" "!7F!">nul && goto[Loop]
- set/a "i+=1" &echo,!i!: !mF!>>"!7F!"
- start "" "!mF!"
- endlocal &exit/b
复制代码
作者: yanni_enya 时间: 2023-12-26 09:12
本帖最后由 yanni_enya 于 2023-12-26 09:14 编辑
回复 24# aloha20200628
可以用!而且修改后直接跟在之前的已播列表记录后边,序号都是跟着的!
作者: _avatar_ 时间: 2023-12-30 19:59
回复 9# yanni_enya
似乎你并没有理解我的代码,脚本并不需要人为判断,我是通过获取打开脚本时你电脑的当前时间变化来计算天数的,如果日期不变,天数计算就不变。
也就是说,我脚本中是没有限制每天播放歌曲的次数的,只要你歌曲数量足够,你可以每天运行100次脚本,随机播放100首歌,并且七天内都不会有重复歌曲,七天之后脚本会自动重置,并不需要你手动修改什么。
脚本里唯一需要修改的是你想循环的天数。
至于你说的是通过调用另一个bat 脚本来播放歌曲,因为你最开始并没有说明这些,我也就没办法预知。
可能是我想得太多,你只需要每天播放一首歌,我想着是不限制每天播放的次数,只保证在七天内不会出现重复歌曲。
作者: czjt1234 时间: 2023-12-30 21:14
回复 26# _avatar_
编程最大的困扰就是甲方需求描述不明,或自己都没明白
作者: yanni_enya 时间: 2024-1-3 14:16
回复 26# _avatar_
嗯,理解你说的。本身需求每天播放次数不多,前边发的那些假设就是每天播一首。
每首歌单独一个bat是因为电脑平常需要静音状态,而每首歌长度又不同,为了播放时自动解除静音,播放后第一时间自动加静音,所以会给每首歌单独一个批处理。
我也想代码越简单越好,只是个人能力确实有限,暂时想不到更好的办法。
作者: yanni_enya 时间: 2024-1-7 20:26
回复 24# aloha20200628
这周末刚好把歌曲放完了一轮,自动开启了第二轮播放,当前已放了一首了,问题是歌曲播放后生成的记录前边的编号没有从1开始,而是顺延了一个数字38,能否让序号再次从1开始?(当前37首歌)
作者: aloha20200628 时间: 2024-1-8 00:24
回复 29# yanni_enya
已订正,新版代码如下- @echo off &setlocal enabledelayedexpansion
- set "i=0" &set "7F=D:\jhrw\现用音乐\music\list.7"
- if not exist "!7F!" (cd.>"!7F!") else for /f %%k in ('find /v /c "" ^<"!7F!" ') do (set "i=%%k" &if %%k geq 7 (cd.>"!7F!"&set "i=0"))
- for %%b in ("D:\jhrw\现用音乐\music\*.bat") do (set/a "n+=1" &set "$!n!=%%b")
- :[Loop]
- set/a m=%random%%%%n%+1
- for %%k in (!m!) do (set "mF=!$%%k!")
- find /i "!mF!" "!7F!">nul && goto[Loop]
- set/a "i+=1" &echo,!i!: !mF!>>"!7F!"
- start "" "!mF!"
- endlocal &exit/b
复制代码
作者: yanni_enya 时间: 2024-1-8 09:04
回复 30# aloha20200628
管用!
作者: yanni_enya 时间: 2024-10-19 10:04
回复 30# aloha20200628
可否在每条播放记录后边加上播放曲目当天的日期
作者: aloha20200628 时间: 2024-10-19 10:39
本帖最后由 aloha20200628 于 2024-10-19 11:33 编辑
回复 32# yanni_enya - @echo off &setlocal enabledelayedexpansion
- set "i=0" &set "7F=D:\jhrw\现用音乐\music\list.7"
- if not exist "!7F!" (cd.>"!7F!") else for /f %%k in ('find /v /c "" ^<"!7F!" ') do (set "i=%%k" &if %%k geq 7 (cd.>"!7F!"&set "i=0"))
- for %%b in ("D:\jhrw\现用音乐\music\*.bat") do (set/a "n+=1" &set "$!n!=%%b")
- :[Loop]
- set/a m=%random%%%%n%+1
- for %%k in (!m!) do (set "mF=!$%%k!")
- find /i " !mF! " "!7F!">nul && goto[Loop]
- set/a "i+=1" &echo,!i!: !mF! %date:~0,10%>>"!7F!"
- start "" "!mF!"
- endlocal &exit/b
复制代码
作者: yanni_enya 时间: 2024-10-19 15:03
回复 33# aloha20200628
感谢!大神再请教一个,
最近维护机房需要一个批处理具备一下功能:
1、获取学生机电脑硬盘大小和内存大小,生成记事本,并用获取的硬盘大小、内存大小和计算机名命名记事本,具体这个样子:240g&4g&A6 (分隔符&可以用别的符号替代)
2、生成记事本后,拷贝该记事本到教师机的Y文件夹内(教师机有访问密码,比如ffu,账号是administrator)。
作者: aloha20200628 时间: 2024-10-19 16:12
回复 34# yanni_enya
依照论坛的规则,此求与本帖主题不符,还是应用 http://www.bathome.net/thread-69969-1-1.html 求解吧
作者: yanni_enya 时间: 2024-10-19 21:55
回复 35# aloha20200628
已经很感谢了,好的~
作者: yanni_enya 时间: 2024-10-21 14:55
回复 35# aloha20200628
您是用wmic编的代码吗?可否推荐本自学的书~
作者: aloha20200628 时间: 2024-10-21 16:39
回复 37# yanni_enya
wmic有两种应用方式,交互方式和命令行调用方式,批处调用wmic功能是采用第二种方式
论坛老帖中有很多有关批处调用wmic的示例可供学习摸索,另给一个链接以供参考 https://www.cnblogs.com/liujunjun/p/18101437
欢迎光临 批处理之家 (http://bbs.bathome.net/) |
Powered by Discuz! 7.2 |