控制某个 MP 对象在播放音频文件时更改音量设置
To control a certain MP object to alter volume settings while playing an audio file
我的 .bat
脚本中有这段代码。
( echo Set Sound = CreateObject("WMPlayer.OCX.7"^)
echo Sound.URL = "music\sia.mp3"
echo Sound.settings.volume = %volume%
echo Sound.settings.setMode "loop", True
echo Sound.Controls.play
echo While Sound.playState ^<^> 1
echo WScript.Sleep 100
echo Wend
)>sound22.vbs
start /min sound22.vbs
del *.vbs
它只是在后台无限循环播放 music\sia.mp3
。
有时它无法执行 sound22.vbs
因为它在糟糕的代码甚至可以执行它之前就删除了它。
但是,我的主要问题是:
( echo Set Sound = CreateObject("WMPlayer.OCX.7"^)
echo Sound.settings.volume = %volume2%
echo While Sound.playState ^<^> 1
echo WScript.Sleep 100
echo Wend
)>sound22.vbs
start /min sound22.vbs
del *.vbs
此代码本应将当前音量更改为 %volume2%
,但并未重播音乐。
- 我该怎么做?
- 如何控制我之前创建的
WMPlayer
对象?
- 即使我这样做,2.,第二个代码是否能够在不重播或暂停音乐的情况下改变音量?
- 我可以用同样的方法
sound.controls.pause
暂停并再次继续播放吗?
批量尝试此示例:
@echo off
Mode 60,5 & color 0A
Set "Volume=20"
Set "Title=Playing Music with volume of"
Title %Title% %Volume%%%
Set "URL=https://stream.initialradio.fr:8443/djbuzz-192k.mp3"
Set "VBS_Music=%Temp%\VBS_Music.vbs"
echo(
echo Playing Radio Music with the volume of %Volume%%%
Call :PlayMusic "%URL%" %Volume%
Timeout /T 10 /nobreak>nul & cls & echo(
Set "Volume=100"
Title %Title% %Volume%%%
echo Playing Radio Music with the volume of %Volume%%%
Call :StopMusic
Call :PlayMusic "%URL%" %Volume%
echo(
echo Hit any key to stop the music and exit !
Pause>nul
Call :StopMusic
Exit
::*******************************************************************
:PlayMusic <URL> <Volume>
(
echo Call Play("%~1",%2^)
echo Sub Play(URL,Volume^)
echo Set wmp = CreateObject("WMPlayer.OCX"^)
echo wmp.settings.autoStart = True
echo wmp.settings.volume = Volume
echo wmp.URL = URL
echo While wmp.Playstate ^<^> 1
echo WScript.Sleep 100
echo Wend
echo End Sub
)>"%VBS_Music%"
Start "" "%VBS_Music%"
exit /b
::*******************************************************************
:StopMusic
Call :Add_backSlash "%VBS_Music%"
wmic Path win32_process Where "CommandLine Like '%%%Cmd_Path%%%'" Call Terminate>nul 2>&1
exit /b
::*******************************************************************
:Add_backSlash <String>
Rem Subroutine to replace the simple "\" by a double "\" into a String
Set "MyPath=%1"
Set "String=\"
Set "NewString=\"
Call Set "Cmd_Path=%%MyPath:%String%=%NewString%%%"
exit /b
::*******************************************************************
您无法通过创建一个新对象来控制先前创建的 WMPlayer
对象,但您可以通过合并一种与创建的对象通信的机制来控制它。
由于批处理脚本没有进程间通信的标准方式,唯一的选择就是使用中间文件作为通信媒介。
以下是一个独立的示例代码,演示了通过批处理脚本执行此操作的一种方法。
它可以以不同的方式编写,但我遵循了您编写代码的设计路径。
它播放指定的music/sound文件并提示用户输入命令发送给播放器来控制它。
执行的控制命令有:[0-100] for volume, mute, unmute, play, pause, replay, stop, open, quit
:: MusicPlayerAndController.bat
@echo off
setlocal DisableDelayedExpansion
set "PlayerMutex=BatchVbsSoundPlayer.mutex"
if "%~1"=="/LaunchAsyncPipedVbsPlayer" (
%= Asynchronous Background Player =%
%= Invoking only one instance of background player in the current directory =%
9>&2 2>nul ( 8>"%PlayerMutex%" 2>&9 (
call :LaunchAsyncPipedVbsPlayer
(call,) %= Masks all other errors except than failure to hold PlayerMutex =%
)) && del "%PlayerMutex%" >nul 2>&1 || echo WARNING: Another instance of player is already running.
exit /b
)
%= Asynchronous Controller =%
cls
title Batch/VBS Music Player And Controller
set "PlayerCommandFile=VBSPlayerCommand.txt"
set "VBScriptPlayerApp=MediaPlayer.vbs"
:: Sample Music from Windows 7
set "SoundFile=%PUBLIC%\Music\Sample Music\Sleep Away.mp3"
if not exist "%SoundFile%" (
set "SoundFile="
echo Open a media file to start playing.
)
set "InitialVolume=30"
set "PingPipe=pingpipe"
(
echo Dim Input : Dim Open
echo Open = False
echo Set Sound = CreateObject("WMPlayer.OCX.7"^)
echo Sound.URL = "%SoundFile%"
echo Sound.settings.volume = %InitialVolume%
echo Sound.settings.setMode "loop", True
echo Sound.Controls.play
echo 'Give enough time for preparing new media, not relying on 'pingpipe' intervals
echo WScript.Sleep 1000
echo Do Until WScript.StdIn.AtEndOfStream
echo Input = WScript.StdIn.ReadLine^(^)
echo If IsNumeric^(Input^) Then
echo Sound.settings.volume = Input
echo ElseIf Open = True Then
echo Open = False
echo Sound.Controls.stop
echo Sound.URL = Input
echo Sound.Controls.play
echo 'Give enough time for preparing new media, not relying on 'pingpipe' intervals
echo WScript.Sleep 1000
echo Else
echo Select Case Trim^(LCase^(Input^)^)
echo Case "quit"
echo Exit Do
echo Case "stop"
echo Sound.Controls.stop
echo Case "pause"
echo Sound.Controls.pause
echo Case "play"
echo Sound.Controls.play
echo Case "replay"
echo Sound.Controls.stop
echo Sound.Controls.play
echo Case "mute"
echo Sound.settings.mute = True
echo Case "unmute"
echo Sound.settings.mute = False
echo Case "open"
echo Open = True
echo Case "%PingPipe%"
echo 'Workaround for StdIn blokcing player from looping media
echo WScript.Sleep 1
echo End Select
echo End If
echo Loop
echo Sound.Controls.stop
echo Sound.close
)>"%VBScriptPlayerApp%"
:: Workaround for CMD %~0 bug
call :getBatFullPath @f0
:: Starting player
start "" /B "%COMSPEC%" /D /C "%@f0%" /LaunchAsyncPipedVbsPlayer
:: Give the player enough time to start
timeout /t 1 /nobreak >nul
del "%VBScriptPlayerApp%" >nul 2>&1
set "PlayerCommand=NONE"
set "QuitMsg=Player Closed."
:: Controller Command Loop
:PlayerCommandPrompt
set "LastCommand=%PlayerCommand%"
:PromptPreserveLastCommand
:: Making sure player is alive
del "%PlayerMutex%" >nul 2>&1
if not exist "%PlayerMutex%" (
set "QuitMsg=Player Closed unexpectedly."
goto :Quit
)
echo,
echo VbsPlayer Command Prompt
echo Valid Commands:
echo [0-100] for volume, mute, unmute, play, pause, replay, stop, open, quit, cls (Clears Screen)
echo,
echo Last Command Sent: %LastCommand%
echo,
set "PlayerCommand="
set /p "PlayerCommand=Enter Command to send to VBS Player>"
if not defined PlayerCommand goto :PromptPreserveLastCommand
if /i "%PlayerCommand%"=="cls" cls & goto :PromptPreserveLastCommand
if /i "%PlayerCommand%"=="open" (
setlocal EnableDelayedExpansion
set "OK="
set "NewMedia="
set /p "NewMedia=Media File (Drag'n'Drop): "
if defined NewMedia (
set ^"NewMedia=!NewMedia:^"=!^"
if exist "!NewMedia!" (
(echo open&echo !NewMedia!)>"!PlayerCommandFile!"
set "OK=1"
)
)
if defined OK (
endlocal
goto :PlayerCommandPrompt
) else (
endlocal
goto :PromptPreserveLastCommand
)
)
(echo %PlayerCommand%)>"%PlayerCommandFile%"
if /i "%PlayerCommand%"=="quit" goto :Quit
goto :PlayerCommandPrompt
:Quit
echo,
echo %QuitMsg%
pause
exit /b
:LaunchAsyncPipedVbsPlayer
del /f "%PlayerCommandFile%" >nul 2>&1
(
(
for /L %%# in (0,0,1) do @(
type "%PlayerCommandFile%" && del "%PlayerCommandFile%" >&2
timeout /t 1 /nobreak >&2
%= This guarantees we will not loop infinitely when the player is closed =%
%= Also used as a workaround for player 'loop music' to function correctly =%
echo %PingPipe% 2>&1
)
)2>nul
)|cscript //nologo "%VBScriptPlayerApp%"
exit /b
:getBatFullPath
set "%~1=%~f0" & exit /b
它通过批处理代码读取文件并通过已建立的管道将数据发送到 VBS
代码。
VBS
代码可以简单地自行读取文件而无需使用管道,但后来我不得不将更大更复杂的 VBS
代码嵌入到批处理文件中 echo
命令,除非您决定将 VBS
代码与批处理代码分开。
或者 VBS
部分可以转换为 JS
,这使您能够使用真正的 BAT/JS
混合代码,而无需将 JS
部分写入每次执行脚本时单独的文件。
我的 .bat
脚本中有这段代码。
( echo Set Sound = CreateObject("WMPlayer.OCX.7"^)
echo Sound.URL = "music\sia.mp3"
echo Sound.settings.volume = %volume%
echo Sound.settings.setMode "loop", True
echo Sound.Controls.play
echo While Sound.playState ^<^> 1
echo WScript.Sleep 100
echo Wend
)>sound22.vbs
start /min sound22.vbs
del *.vbs
它只是在后台无限循环播放 music\sia.mp3
。
有时它无法执行 sound22.vbs
因为它在糟糕的代码甚至可以执行它之前就删除了它。
但是,我的主要问题是:
( echo Set Sound = CreateObject("WMPlayer.OCX.7"^)
echo Sound.settings.volume = %volume2%
echo While Sound.playState ^<^> 1
echo WScript.Sleep 100
echo Wend
)>sound22.vbs
start /min sound22.vbs
del *.vbs
此代码本应将当前音量更改为 %volume2%
,但并未重播音乐。
- 我该怎么做?
- 如何控制我之前创建的
WMPlayer
对象? - 即使我这样做,2.,第二个代码是否能够在不重播或暂停音乐的情况下改变音量?
- 我可以用同样的方法
sound.controls.pause
暂停并再次继续播放吗?
批量尝试此示例:
@echo off
Mode 60,5 & color 0A
Set "Volume=20"
Set "Title=Playing Music with volume of"
Title %Title% %Volume%%%
Set "URL=https://stream.initialradio.fr:8443/djbuzz-192k.mp3"
Set "VBS_Music=%Temp%\VBS_Music.vbs"
echo(
echo Playing Radio Music with the volume of %Volume%%%
Call :PlayMusic "%URL%" %Volume%
Timeout /T 10 /nobreak>nul & cls & echo(
Set "Volume=100"
Title %Title% %Volume%%%
echo Playing Radio Music with the volume of %Volume%%%
Call :StopMusic
Call :PlayMusic "%URL%" %Volume%
echo(
echo Hit any key to stop the music and exit !
Pause>nul
Call :StopMusic
Exit
::*******************************************************************
:PlayMusic <URL> <Volume>
(
echo Call Play("%~1",%2^)
echo Sub Play(URL,Volume^)
echo Set wmp = CreateObject("WMPlayer.OCX"^)
echo wmp.settings.autoStart = True
echo wmp.settings.volume = Volume
echo wmp.URL = URL
echo While wmp.Playstate ^<^> 1
echo WScript.Sleep 100
echo Wend
echo End Sub
)>"%VBS_Music%"
Start "" "%VBS_Music%"
exit /b
::*******************************************************************
:StopMusic
Call :Add_backSlash "%VBS_Music%"
wmic Path win32_process Where "CommandLine Like '%%%Cmd_Path%%%'" Call Terminate>nul 2>&1
exit /b
::*******************************************************************
:Add_backSlash <String>
Rem Subroutine to replace the simple "\" by a double "\" into a String
Set "MyPath=%1"
Set "String=\"
Set "NewString=\"
Call Set "Cmd_Path=%%MyPath:%String%=%NewString%%%"
exit /b
::*******************************************************************
您无法通过创建一个新对象来控制先前创建的 WMPlayer
对象,但您可以通过合并一种与创建的对象通信的机制来控制它。
由于批处理脚本没有进程间通信的标准方式,唯一的选择就是使用中间文件作为通信媒介。
以下是一个独立的示例代码,演示了通过批处理脚本执行此操作的一种方法。
它可以以不同的方式编写,但我遵循了您编写代码的设计路径。
它播放指定的music/sound文件并提示用户输入命令发送给播放器来控制它。
执行的控制命令有:[0-100] for volume, mute, unmute, play, pause, replay, stop, open, quit
:: MusicPlayerAndController.bat
@echo off
setlocal DisableDelayedExpansion
set "PlayerMutex=BatchVbsSoundPlayer.mutex"
if "%~1"=="/LaunchAsyncPipedVbsPlayer" (
%= Asynchronous Background Player =%
%= Invoking only one instance of background player in the current directory =%
9>&2 2>nul ( 8>"%PlayerMutex%" 2>&9 (
call :LaunchAsyncPipedVbsPlayer
(call,) %= Masks all other errors except than failure to hold PlayerMutex =%
)) && del "%PlayerMutex%" >nul 2>&1 || echo WARNING: Another instance of player is already running.
exit /b
)
%= Asynchronous Controller =%
cls
title Batch/VBS Music Player And Controller
set "PlayerCommandFile=VBSPlayerCommand.txt"
set "VBScriptPlayerApp=MediaPlayer.vbs"
:: Sample Music from Windows 7
set "SoundFile=%PUBLIC%\Music\Sample Music\Sleep Away.mp3"
if not exist "%SoundFile%" (
set "SoundFile="
echo Open a media file to start playing.
)
set "InitialVolume=30"
set "PingPipe=pingpipe"
(
echo Dim Input : Dim Open
echo Open = False
echo Set Sound = CreateObject("WMPlayer.OCX.7"^)
echo Sound.URL = "%SoundFile%"
echo Sound.settings.volume = %InitialVolume%
echo Sound.settings.setMode "loop", True
echo Sound.Controls.play
echo 'Give enough time for preparing new media, not relying on 'pingpipe' intervals
echo WScript.Sleep 1000
echo Do Until WScript.StdIn.AtEndOfStream
echo Input = WScript.StdIn.ReadLine^(^)
echo If IsNumeric^(Input^) Then
echo Sound.settings.volume = Input
echo ElseIf Open = True Then
echo Open = False
echo Sound.Controls.stop
echo Sound.URL = Input
echo Sound.Controls.play
echo 'Give enough time for preparing new media, not relying on 'pingpipe' intervals
echo WScript.Sleep 1000
echo Else
echo Select Case Trim^(LCase^(Input^)^)
echo Case "quit"
echo Exit Do
echo Case "stop"
echo Sound.Controls.stop
echo Case "pause"
echo Sound.Controls.pause
echo Case "play"
echo Sound.Controls.play
echo Case "replay"
echo Sound.Controls.stop
echo Sound.Controls.play
echo Case "mute"
echo Sound.settings.mute = True
echo Case "unmute"
echo Sound.settings.mute = False
echo Case "open"
echo Open = True
echo Case "%PingPipe%"
echo 'Workaround for StdIn blokcing player from looping media
echo WScript.Sleep 1
echo End Select
echo End If
echo Loop
echo Sound.Controls.stop
echo Sound.close
)>"%VBScriptPlayerApp%"
:: Workaround for CMD %~0 bug
call :getBatFullPath @f0
:: Starting player
start "" /B "%COMSPEC%" /D /C "%@f0%" /LaunchAsyncPipedVbsPlayer
:: Give the player enough time to start
timeout /t 1 /nobreak >nul
del "%VBScriptPlayerApp%" >nul 2>&1
set "PlayerCommand=NONE"
set "QuitMsg=Player Closed."
:: Controller Command Loop
:PlayerCommandPrompt
set "LastCommand=%PlayerCommand%"
:PromptPreserveLastCommand
:: Making sure player is alive
del "%PlayerMutex%" >nul 2>&1
if not exist "%PlayerMutex%" (
set "QuitMsg=Player Closed unexpectedly."
goto :Quit
)
echo,
echo VbsPlayer Command Prompt
echo Valid Commands:
echo [0-100] for volume, mute, unmute, play, pause, replay, stop, open, quit, cls (Clears Screen)
echo,
echo Last Command Sent: %LastCommand%
echo,
set "PlayerCommand="
set /p "PlayerCommand=Enter Command to send to VBS Player>"
if not defined PlayerCommand goto :PromptPreserveLastCommand
if /i "%PlayerCommand%"=="cls" cls & goto :PromptPreserveLastCommand
if /i "%PlayerCommand%"=="open" (
setlocal EnableDelayedExpansion
set "OK="
set "NewMedia="
set /p "NewMedia=Media File (Drag'n'Drop): "
if defined NewMedia (
set ^"NewMedia=!NewMedia:^"=!^"
if exist "!NewMedia!" (
(echo open&echo !NewMedia!)>"!PlayerCommandFile!"
set "OK=1"
)
)
if defined OK (
endlocal
goto :PlayerCommandPrompt
) else (
endlocal
goto :PromptPreserveLastCommand
)
)
(echo %PlayerCommand%)>"%PlayerCommandFile%"
if /i "%PlayerCommand%"=="quit" goto :Quit
goto :PlayerCommandPrompt
:Quit
echo,
echo %QuitMsg%
pause
exit /b
:LaunchAsyncPipedVbsPlayer
del /f "%PlayerCommandFile%" >nul 2>&1
(
(
for /L %%# in (0,0,1) do @(
type "%PlayerCommandFile%" && del "%PlayerCommandFile%" >&2
timeout /t 1 /nobreak >&2
%= This guarantees we will not loop infinitely when the player is closed =%
%= Also used as a workaround for player 'loop music' to function correctly =%
echo %PingPipe% 2>&1
)
)2>nul
)|cscript //nologo "%VBScriptPlayerApp%"
exit /b
:getBatFullPath
set "%~1=%~f0" & exit /b
它通过批处理代码读取文件并通过已建立的管道将数据发送到 VBS
代码。
VBS
代码可以简单地自行读取文件而无需使用管道,但后来我不得不将更大更复杂的 VBS
代码嵌入到批处理文件中 echo
命令,除非您决定将 VBS
代码与批处理代码分开。
或者 VBS
部分可以转换为 JS
,这使您能够使用真正的 BAT/JS
混合代码,而无需将 JS
部分写入每次执行脚本时单独的文件。