VBA关于声音的多种实现方法

1 用VBA播放声音的方法

  • 需要调用windows里的api (添加头文件,调用模块)
  • 以下这几个方法,都只适合播放小音频,因为这些方法是把这些文件读入内存了,比较费。
  • 以下的这几个方法,只试过支持.wav 不知道是否支持.mp3
  • 在其他语言里,这个文件的路径""的斜杠,可能需要转义,比如写两个 \\ 的斜杠转义

 

1.1 用 sndPlaySound32() 播放声音文件

  • 需要调用API 如 Function sndPlaySound32 Lib "winmm.dll" Alias "sndPlaySoundA"
  • Private Declare PtrSafe Function sndPlaySound32 Lib "winmm.dll" Alias "sndPlaySoundA" (ByVal lpszName As String, ByVal uFlags As Long) As Long
  • 如果是64位系统,需要加 PtrSafe 关键字,否则不需要
  •  
  • sndPlaySound32(文件参数)       参数这写声音文件的绝对路径就行
  • 参数1:声音文件,应该可以支持 .wav  
  • 参数2:0 或0 &
Private Declare PtrSafe Function sndPlaySound32 Lib "winmm.dll" Alias "sndPlaySoundA" (ByVal lpszName As String, ByVal uFlags As Long) As Long

Sub test1()

Call sndPlaySound32("F:\cowork\俄罗斯方块\true2.wav", 0&)  '这里写声音文件的绝对路径就行

End Sub

 

1.2 用 sndPlaySound() 播放声音文件

  • 需要调用API 如 Function sndPlaySound Lib "winmm.dll" Alias "sndPlaySoundA"
  • Private Declare PtrSafe Function sndPlaySound Lib "winmm.dll" Alias "sndPlaySoundA" (ByVal lpszSoundName As String, ByVal uFlags As Long) As Long
  • 如果是64位系统,需要加 PtrSafe 关键字,否则不需要
  •  
  • sndPlaySound  参数1,参数2
  • call sndPlaySound (参数1,参数2)
  • 参数1:声音文件,绝对路径
  • 参数2:
  • SND_ASYNC 异步 ,也可以用1,播放开始后即往下执行了
  • SND_SYNC 同步 ,也可以用0,播放完了才往下执行
  • SND_NODEFAULT ?给目录用的?
  • BOOL sndPlaySound(LPCSTR lpszSound, UINT fuSound);
  • SND_ASYNC、SND_LOOP、SND_MEMORY、SND_NODEFAULT、SND_NOSTOP和SND_SYNC的组合

  • 关闭方法:播放一个不存在的声音文件
  • call  sndPlaySound("",1) 
Private Declare PtrSafe Function sndPlaySound Lib "winmm.dll" Alias "sndPlaySoundA" (ByVal lpszSoundName As String, ByVal uFlags As Long) As Long


Sub testSound2()

sndPlaySound "F:\cowork\FangCloudV2\个人文件\2学习\4EXCEL和VBA\3VBA项目\俄罗斯方块\true2.wav", SND_ASYNC

End Sub

这样也可以

Sub testSound2()

sndPlaySound "F:\cowork\FangCloudV2\个人文件\2学习\4EXCEL和VBA\3VBA项目\俄罗斯方块\true2.wav", SND_NODEFAULT

End Sub

 

1.3 用 PlaySound() 播放声音文件

  • 需要调用API 如 Function PlaySound Lib "winmm.dll" Alias "PlaySoundA"
  • Private Declare PtrSafe Function PlaySound Lib "winmm.dll" Alias "PlaySoundA" (ByVal lpszName As String, ByVal hModule As Long, ByVal dwFlags As Long) As Long
  • 如果是64位系统,需要加 PtrSafe 关键字,否则不需要
  •  
  • PlaySound
  • call  PlaySound()
  • PlaySound 参数1 参数2 参数3
  • 参数1:文件名
  • 参数2:必须是0
  • 参数3:1 后台播放,8循环播放,9(1+8)后台循环播放
  • 关闭方法:播放一个不存在的声音文件
  • call  PlaySound("",0,1) 
  • BOOL PlaySound(LPCSTR pszSound, HMODULE hmod,DWORD fdwSound);

 

Private Declare PtrSafe Function PlaySound Lib "winmm.dll" Alias "PlaySoundA" (ByVal lpszName As String, ByVal hModule As Long, ByVal dwFlags As Long) As Long


Sub testSound3()

Call PlaySound("F:\cowork\FangCloudV2\个人文件\2学习\4EXCEL和VBA\3VBA项目\俄罗斯方块\true2.wav", 0, 8)

End Sub

 

 

1.4 播放声音的不同方式,外部调用等(这部分转载,学习)

1. 通过filename来定位文件播放

PlaySound(TEXT("c:\\crossing field.wav"), NULL, SND_FILENAME | SND_ASYNC); // TEXT()函数处理宽字符问题,SND_FILENAME标识采用文件名播放,SND_ASYNC标识异步播放,即PlaySound函数开始播放后便返回执行代码而不是等到播放完了再执行(此种方式对应SND_SYNC) 
sndPlaySound(TEXT("c:\\crossing field.wav"), SND_FILENAME | SND_ASYNC);

2. 通过资源文件播放

首先将wav文件添加进资源.rc文件,假设文件ID为IDR_WAVE1,则代码如下

PlaySound((LPCTSTR)IDR_WAVE1, NULL, SND_RESOURCE | SND_ASYNC | SND_LOOP); // 将文件ID强制转换为LPCTSTR型数据,然后标明是采用资源文件的形式播放(SND_RESOURCE),异步(SND_ASYNC),循环(SND_LOOP)
sndPlaySound((LPCTSTR)IDR_WAVE1, SND_RESOURCE | SND_ASYNC | SND_LOOP); // 同PlaySound

第一种方式是外部调用,所以生成的exe文件很小,而第二种第三种会把wav文件压进exe文件,所以文件会变得特别大……

 

1.5 EXCEL也可以用  windowsMediaPlayer

  • 先在excel里插入 mediaPlayer
  • 开发工具---插入---其他控件
  • 选择 Windows mediaPlayer

  

 

 

使用这段代码可以播放音乐

Sub 播放()
Sheets("sheet2").WindowsMediaPlayer1.URL = ThisWorkbook.Path & "\true2.wav"
Sheets("sheet2").WindowsMediaPlayer1.Controls.Play  '播放
End Sub

'Sheets("sheet1").WindowsMediaPlayer1.Controls.stop  '停止播放
'Application.OnTime "15:07", "播放"         '设定播放时间

 

1.6 通过beep API

  • API
  • 响铃API函数声明
  • Private Declare PtrSafe Function Beep Lib "kernel32" (ByVal dwFreq As Long, ByVal dwDuration As Long) As Long  
  • 参数
  • dwFreq:Long型,声音频率(从37Hz到32767Hz)。
  • dwDuration:Long型,声音的持续时间,以毫秒为单位。如为-1,表示一直播放声音,直到再次调用该函数为止。

测试基本的beep2个参数效果

Private Declare PtrSafe Function Beep Lib "kernel32" (ByVal dwFreq As Long, ByVal dwDuration As Long) As Long  '响铃API函数声明
 
 
Sub play1()
    'beep 频率,持续时间duration 毫秒

    Beep 100, 500
    Beep 1000, 500
    Beep 3000, 500
    
    Beep 2000, 400
    Beep 2000, 800
    Beep 2000, 1500
    
    
    DoEvents
End Sub

 

 

1.7 Application.Speech.Speak

  • 这样是不是可以实现人机对话了?
  • 写法1:
  • Application.Speech.Speak ""
  • 写法2:
  • range.speak
  • 写法3:
  • CreateObject("SAPI.SpVoice").Speak Range("A1").Value


Sub play2()

Application.Speech.Speak "hello"
Application.Speech.Speak "It's time to do something."
Application.Speech.Speak "fire in the hole."


End Sub

 

  • 很好玩,还可以读中文,实测可行
Sub play3()

Application.Speech.Speak Range("a1").Value


End Sub

 

 

range.speak

selection.speak

Sub play3()

Application.Speech.Speak Range("a1").Value    '试了下是串行的,同步执行
Range("a2").Speak
Selection.Speak

End Sub

 

CreateObject("SAPI.SpVoice").Speak Range("A1").Value

Sub play4()

CreateObject("SAPI.SpVoice").Speak Range("A1").Value

End Sub

 

大神的语速例子,VBS的代码

Sub test11()



Dim objSV
Set objSV = CreateObject("SAPI.SpVoice")
objSV.Speak ("大家好,我是" & objSV.Voice.GetDescription & ",下面我给大家说一段绕口令.")
objSV.Rate = 5
objSV.Speak ("巴老爷有八十八棵芭蕉树 来了八十八个把式要在巴老爷八十八棵芭蕉树下住 巴老爷拔了八十八棵芭蕉树 不让八十八个把式在八十八棵芭蕉树下住 八十八个把式烧了八十八棵芭蕉树 巴老爷在八十八棵树边哭")
objSV.Rate = 0
objSV.Speak ("太快了屌爆了有木有,我慢一点再说一次吧.")
objSV.Rate = 3
objSV.Speak ("巴老爷有八十八棵芭蕉树 来了八十八个把式要在巴老爷八十八棵芭蕉树下住 巴老爷拔了八十八棵芭蕉树 不让八十八个把式在八十八棵芭蕉树下住 八十八个把式烧了八十八棵芭蕉树 巴老爷在八十八棵树边哭")
objSV.Rate = 0
objSV.Speak ("本期节目到此结束.谢谢收听!")

End Sub

 

https://jingyan.baidu.com/article/4f7d5712a6e0671a20192716.html

https://tieba.baidu.com/p/2026221833

 

 

 

 

Private Sub Worksheet_Change(ByVal Target As Range)

On Error Resume Next '因为表上内容倍全删后,下面方法会报错
Application.Speech.Speak Target, True

End Sub

可实现每次sheet内容改变后,自动读语音

 

指定读一列或部分得也可以

Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Column = 4 Then


'Target.Speak  '无法操作其他
Application.Speech.Speak Target, True

End If
End Sub

 

 

target.value    取其中得数值来读

target.text  取其中得文本,小数点也会读出来

speech.speak "",0,0,0

speech.speak "",1,0,0  '允许异步,处理其他,否则默认是同步无法响应

speech.speak "",1,0,1  '打断效果未试验出来

 

多句放一起得时候,需要每个都是 1/true 才会异步

speech.speak "",1,0,0

speech.speak "",1,0,0

 

实测很多问题

https://blog.csdn.net/sysdzw/article/details/90680255

 

 

如果像停止声音?

在主程序代码中,应该是在循环操作过程的任意位置(或你喜欢的位置)中,
插入如下代码:

For i = 1 To N
……
DoEvents
If [a1] = "" Then '这里的[a1] = "" 为终止条件,可以自己重新定义
Exit Sub 或END
End If
……
Next


++++++++++++++++++

然后,另外写一个终止条件的代码,比如:
Sub StopMacro()
    [a1] = ""   '终止条件,可以自己改条件
End Sub

++++++++++++++++++

然后,在工作簿或窗体上加入这个可执行终止代码的宏的按钮即可。

 

 

https://tieba.baidu.com/p/4089338277?red_tag=3448404053

 

这个可以达到和放在worksheet change里得事件一样得效果

会一直监测这个单元格 (监控全表?)


Sub ttf7()

Application.Speech.SpeakCellOnEnter = True
Application.Speech.Speak Range("H13")



End Sub

 

 

https://docs.microsoft.com/zh-cn/office/vba/api/excel.application.showtooltips

https://docs.microsoft.com/zh-cn/office/vba/api/excel.speech.direction

 

 

Application.Speech.Direction = xlSpeakByRows

 

https://tieba.baidu.com/p/138682414?red_tag=0595033674

 

 

 

 

 

 

 

 

 

 

 

 

2 在窗体里播放声音和视频文件

2.1 在窗体里用 windowsMediaPlayer的播放器,播放声音,甚至视频?

  1. 创建窗体
  2. 增加windowsMediaPlayer的播放器
  3. 增加控制按钮,给窗体里增加代码
  4. 然后,运行窗体
  5. 点击按钮

 

2.2 如何增加windowsMediaPlayer的播放器

  

    

   

2.3 代码

  • 其中WindowsMediaPlayer1是控件的名称
  • 关键代码
  • WindowsMediaPlayer1.URL = path1 & "true2.wav"
  • 需要是绝对路径,但也可以取得文件 path 再组合相对路径称为 可支持移动 的绝对路径,将表格和资源打包在一起。
  • WindowsMediaPlayer1.Controls.Play
  • 控制播放
Private Sub CommandButton1_Click()

path1 = ThisWorkbook.Path & "\"

WindowsMediaPlayer1.URL = path1 & "true2.wav"
WindowsMediaPlayer1.Controls.Play


End Sub

Private Sub WindowsMediaPlayer1_OpenStateChange(ByVal NewState As Long)

End Sub

  

 

 

 

 

 

 

 音乐控件的播放

  • 播放音乐的属性
  • 播放器.url
  • 播放器.controls.play    

 

  • WindowsMediaPlayer1.URL = "C:\Users\Administrator\Desktop\rain.mp3"
  • WindowsMediaPlayer1.Controls.Play
     

   

 

Private Sub WindowsMediaPlayer1_Click(ByVal nButton As Integer, ByVal nShiftState As Integer, ByVal fX As Long, ByVal fY As Long)

WindowsMediaPlayer1.URL = "C:\Users\Administrator\Desktop\rain.mp3"
WindowsMediaPlayer1.Controls.Play

End Sub

 

2 用加载lib 调用API的方法

 

Declare Function mciExecute Lib "winmm.dll" (ByVal lpstrCommand As String) As Long
Sub auto_open()
    ReturnSoundValue=mciExecute("open " & ThisWorkbook.Path &
    "\上海滩.mid ALIAS rsv")
    mciExecute "play rsv"
End Sub
Sub关闭()
    mciExecute "close rsv"
End Sub

 

 

 

 

是不是只能播放MP3?

 

 

 

一次播放多个MP3?

http://club.excelhome.net/thread-1400639-1-1.html

 

其他方法

http://www.excelpx.com/thread-177197-1-1.html

 

用shell?

http://club.excelhome.net/thread-553187-1-1.html

 

 

 

 

 

 

 

http://www.cnitblog.com/asfman/articles/35982.html

https://www.cnblogs.com/keno/archive/2013/01/30/MediaPlayer.html

wmp.dll控件常用属性 
    本人在网上收集到windows media player 控件的一些属性,望对有需要的朋友有所帮助。(在计算机中装了wmp9以上,就会有wmp.dll控件,属性如下所示)
属性/方法名: 说明:
[基本属性]  
URL:String; 指定媒体位置,本机或网络地址
uiMode:String; 播放器界面模式,可为Full, Mini, None, Invisible
playState:integer; 播放状态,1=停止,2=暂停,3=播放,6=正在缓冲,9=正在连接,10=准备就绪
enableContextMenu:Boolean; 启用/禁用右键菜单
fullScreen:boolean; 是否全屏显示
[controls] wmp.controls //播放器基本控制
controls.play; 播放
controls.pause; 暂停
controls.stop; 停止
controls.currentPosition:double; 当前进度
controls.currentPositionString:string; 当前进度,字符串格式。如“00:23”
controls.fastForward; 快进
controls.fastReverse; 快退
controls.next; 下一曲
controls.previous; 上一曲
[settings] wmp.settings //播放器基本设置
settings.volume:integer; 音量,0-100
settings.autoStart:Boolean; 是否自动播放
settings.mute:Boolean; 是否静音
settings.playCount:integer; 播放次数
[currentMedia] wmp.currentMedia //当前媒体属性
currentMedia.duration:double; 媒体总长度
currentMedia.durationString:string; 媒体总长度,字符串格式。如“03:24”
currentMedia.getItemInfo(const string); 获取当前媒体信息"Title"=媒体标题,"Author"=艺术家,"Copyright"=版权信息,"Description"=媒体内容描述,"Duration"=持续时间(秒),"FileSize"=文件大小,"FileType"=文件类型,"sourceURL"=原始地址
currentMedia.setItemInfo(const string); 通过属性名设置媒体信息
currentMedia.name:string; 同 currentMedia.getItemInfo("Title")
[currentPlaylist] wmp.currentPlaylist //当前播放列表属性
currentPlaylist.count:integer; 当前播放列表所包含媒体数
currentPlaylist.Item[integer]; 获取或设置指定项目媒体信息,其子属性同wmp.currentMedia 

//2...
==========WindowsMediaPlayer的常用属性和方法===========
[基本属性] 
URL:string                            可以指定媒体位置 
enableContextMenu:Boolean 显示/不显示播放位置的右键菜单 
fullScreen:boolean                 全屏显示 
stretchToFit:boolean              非全屏状态时是否伸展到最佳大小 
uMode:string                         播放器的模式,full:有下面的控制条; none:只有播放部份没有控制条 
playState:integer                    当前控件状态,下面是三种基本状态: 
3:正在播放 
2:暂停 
1:已停止 
状态变化时会触发OnStatusChange事件 

[controls] 
可通过WindowsMediaPlayer.controls对播放器进行控制并取得相关的一些信息: 
 controls.play;       播放 
 controls.stop;       停止 
 controls.pause;      暂停 
 controls.currentPosition:Double 当前播放进度 
 controls.currentPositionString:string 时间格式的字符串 "0:32" 

[currentMedia] 
可以通过WindowsMediaPlayer.currentMedia取得当前媒体的信息 
 currentMedia.duration  Double 总长度 
 currentMedia.durationString 时间格式的字符串 "4:34" 

[settings] 
可以通过WindowsMediaPlayer.settings对播放器进行设置,包括音量和声道等。 
settings.volume:integer 音量 (0-100) 
settings.balance:integer 声道,通过它应该可以进行立体声、左声道、右声道的控制。 
-->
<input type="button" value='换文件' οnclick="MediaPlayer.controls.src='d:\xx.mid';">

 

WindowsMediaPlayer1.settings.playCount = 设置播放的次数

第n个播放完
n+=1
if 循环.cheked=true  then n-=1
播放(n)

 

 

Private Sub File1_Click()
    WindowsMediaPlayer1.url = App.Path + "\" + File1.List(File1.ListIndex)
    WindowsMediaPlayer1.Controls.play
End Sub
 
Private Sub Form_Load()
    File1.Path = App.Path
End Sub
 
Private Sub WindowsMediaPlayer1_OpenStateChange(ByVal NewState As Long)
    WindowsMediaPlayer1.url = App.Path + "\1.mp3"
    WindowsMediaPlayer1.Controls.play
    'WindowsMediaPlayer1.controls.pause '暂停
    'Controls.currentPosition = 10 '设置bai当前播du放未知zhi
End Sub

播放多个和播放下一曲?

 

 

vb2010如何在windowsmediaplayer结束以后触发下一个事件?比如,结束以后label1.text="天气不错”谢谢啦

假设该控件名bai为axWindowsMediaPlayer1。该控件有一PlayStateChange事件du,触发zhi该事件时检dao查axWindowsMediaPlayer1.playState或e.newState是否为WMPLib.WMPPlayState.wmppsMediaEnded,如是,再执行你zhuan的代码。shu
WMP控件需要依赖WMP,其实有一些更好的方案的,比如说bass(播放绝大多数格式音乐),DirectShow(调用系统自带解码器)等等。

 

VB 如何实时知道Windows mediaplayer的播放状态,比如播放到第几秒了,至少得知道是否在播放,是否停止?

知道播放到第bai几秒的代码du
Private Sub Form_Load()
Timer1.Interval = 500
End Sub
Private Sub Timer1_Timer()
Text1.Text = WindowsMediaPlayer1.Controls.currentPositionString
End Sub
知道是否在播zhi放dao,是zhuan否停止shu的代码
Private Sub WindowsMediaPlayer1_PlayStateChange(ByVal NewState As Long)
If NewState = 1 Then Me.Caption = "停止"
If NewState = 3 Then Me.Caption = "正在播放"
End Sub

 

 

举例bai
Private Sub WindowsMediaPlayer1_PlayStateChange(ByVal NewState As Long)
If NewState = 1 Then '1为停止du(一曲播完zhidao)
WindowsMediaPlayer1.Controls.play '再播放
End If
end sub
NewState判断zhuan这个shu值

 

 

 

 

 

 

    WindowsMediaPlayer1.close

Private Sub UserForm_Click()
    play1.Visible = False
    arr = array("xiao3.mp3","xue3.mp3","sheng1.mp3")
    for each p in arr
        play1.URL = p
        play1.Controls.Play
        Sleep 2000
    next
End Sub

用的是2010版本,其他版本未尝试
首先添加引用: 在 COM 组件中找到 Windows Media Player 并引用
然后在工具箱界面右击选择“选择项” 在新窗口中选择 “Windows Media Player”并确定, 这样就添加了该组件
曾用到的简单设置:

MediaPlayer.uiMode = "none"; //隐藏播放控制条
MediaPlayer.URL = Application.StartupPath + "\\MediaVideo\\Animation.avi"; //播放路径
MediaPlayer.settings.setMode("loop", true); //循环播放
  • 1
  • 2
  • 3

最后结束项目时应释放该资源:

MediaPlayer.close();
MediaPlayer.Controls.Clear();
MediaPlayer.Dispose();

 

2.4 特殊实现

  • 除了实现,点击播放音乐
  • 特定时机判断后,播放音乐
  • 甚至可以隐藏 播放器,但一样可以控制它
  • 可以实现EXCEL,播放背景音乐等等

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值