返回列表 发帖

[文件操作] 批处理如何实现: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
)COPY

不想不重复,就得记录播放过的歌曲

TOP

用批处理怎么实现?

TOP

本帖最后由 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
)COPY
bat小白,请多指教!谢谢!

TOP

测试代码之前请做好备份

TOP

我试着写了一个,脚本的不重复周期通过  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 :eofCOPY

TOP

这样行不,随机到的音乐移动到“已播放”文件里后才播放,当“已播放”文件里的音乐文件数量大于一定数量(默认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
pauseCOPY

TOP

回复 4# 77七


    您的脚本我试了一下:一闪而过!
    我把我的使用环境再说的具体一些,以下内容是已经实现的:电脑默认静音,每次播放前会自动取消静音并设置音量大小,歌曲播放完后自动关闭播放器进程,电脑自动设置静音。
    为了达到这个效果,我给每首歌曲在D:\jhrw\现用音乐\music下都设置了与歌曲名相同的批处理文件(这个批处理用来实现解除静音、设置音量,播歌曲,并在播放完后自动关闭进程和自动加静音)。而随机播放音乐的批处理放在  D:\jhrw\晨乐 ,  执行时实际是随机打开了D:\jhrw\现用音乐\music下歌曲同名的批处理。

TOP

回复 6# _avatar_


    您给的脚本可以用,但是与我的使用环境有出入:
    我给每首歌曲在D:\jhrw\现用音乐\music下都设置了与歌曲名相同的批处理文件(这个批处理用来实现解除静音、设置音量,播歌曲,并在播放完后自动关闭进程和自动加静音)。而随机播放音乐的批处理放在  D:\jhrw\晨乐 ,  执行时实际是随机打开了D:\jhrw\现用音乐\music下歌曲同名的批处理。

    而且您的脚本有人为的判断,我想要7天到了自动重新开始在歌曲里再次随机播放歌曲,新的7天仍然不重复即可。

TOP

回复 7# Five66


    也是个办法,但是运行时一闪而过,我在cmd里看了一下,提示两次:此时不应有%%a。
    我想上传图,总是失败,抱歉。

TOP

回复 8# yanni_enya


   如果要实现你描述的功能,以我的水平,只会使用第三方命令行工具nircmd 和mpv ,用一个批处理就可完成。(如果每个音频都搭配一个批处理,好像有点失去批处理的魅力了...)
已在4楼更新代码,代码已测试。
bat小白,请多指教!谢谢!

TOP

本帖最后由 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"
)
)COPY

TOP

回复 10# yanni_enya


如果需要上传文件,请用使用网盘。

如果需要上传截图,可以找个图床,例如:
http://bbs.bathome.net/thread-60985-1-1.html
我帮忙写的代码不需要付钱。如果一定要给,请在微信群或QQ群发给大家吧。
【微信公众号、微信群、QQ群】http://bbs.bathome.net/thread-3473-1-1.html
【支持批处理之家,加入VIP会员!】http://bbs.bathome.net/thread-67716-1-1.html

TOP

回复 12# idwma


    人狠话不多,直接按要求上代码,优秀~
    您的代码也是一闪而过,问题仍然是:此处不应有 %%a。
    网盘传图片我不会,抱歉没图。

TOP

本帖最后由 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/bCOPY

TOP

返回列表