UnityWwise具体某一音频的暂停恢复和终止播放
Posted 加油小五
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UnityWwise具体某一音频的暂停恢复和终止播放相关的知识,希望对你有一定的参考价值。
【Unity】【Wwise】具体某一音频的暂停、恢复和终止播放
以下内容为个人拙见,欢迎大家指正讨论。
Wwise在Unity中提供的方法中,并没有直接提供(看起来没有直接提供。。)暂停音效的方法。
在游戏中较为常见的需要停止音效(或者说控制音效播放状态)的场景,有在切换场景Loading读条时、某种游戏内置音乐播放器中等等。
音效控制场景建议
- 对于切换场景时(或氛围变化)的音乐切换,推荐在Wwise中创建切换事件来实现,这也是使用Wwise的原因之一,在Wwise中可以圆滑的处理音频之间的切换,也可以通过总线来控制一整组的音频。
- 对于单一音频的控制,则有以下几种方式(重点是第3条):
音效播放状态控制
-
Wwise的Unity集成包里提供的组件
AkEvent
该组件上面提供了
Stop()
方法- 优点:简单
- 缺点:不灵活,依赖于组件;没有暂停、恢复方法。
-
在Wwise工程中定义对应的Stop、Pause、Resume事件,通过发送事件来控制音效
// xxx指代某命名的音频 AkSoundEngine.Post("Stop_xxx"); AkSoundEngine.Post("Pause_xxx"); AkSoundEngine.Post("Resume_xxx");
- 优点:较为灵活,可以在任意地方调用
- 缺点:需要定义3倍于播放事件的操控事件,在Wwise中的工作量巨大;对同一音效的控制分离,难于管理
-
封装Wwise提供的方法来实现Stop、Pause、Resume三种控制
既然在AkEvent中有Stop方法,那么可以深入查看一下内部是怎么实现的,最后就找到了以下方法public static AKRESULT ExecuteActionOnEvent(uint in_eventID, AkActionOnEventType in_ActionType, UnityEngine.GameObject in_gameObjectID, int in_uTransitionDuration, AkCurveInterpolation in_eFadeCurve)
其中的参数
AkActionOnEventType
有以下几种类型
所以由此可以进行以下封装(其中WwiseLogger是自己封装的,方便release中剔除):
/// <param name="soundId">In <see cref="AK.EVENTS"/>.</param> public void Pause(uint soundId, GameObject soundSource = null) // NOTE 经过试验,Wwise的暂停和恢复走的是计数机制,暂停多少次,就需要恢复多少次才能够正常恢复。 if (soundId == InvalidSoundId) WwiseLogger.LogMessage(WwiseLogger.LogLevel.Warning, string.Format("Invalid soundId.", soundId)); return; var result = AkSoundEngine.ExecuteActionOnEvent(soundId, AkActionOnEventType.AkActionOnEventType_Pause, soundSource); if (result != AKRESULT.AK_Success) WwiseLogger.LogMessage(WwiseLogger.LogLevel.Warning, string.Format("Pause wwise event with id <0> failed.", soundId), result); else WwiseLogger.LogMessage(WwiseLogger.LogLevel.Normal, string.Format("Pause event with id <0>.", soundId)); /// <summary> /// Should call the same times with Pause. /// </summary> /// <param name="soundId">In <see cref="AK.EVENTS"/>.</param> public void Resume(uint soundId, GameObject soundSource = null) // NOTE 经过试验,Wwise的暂停和恢复走的是计数机制,暂停多少次,就需要恢复多少次才能够正常恢复。 if (soundId == InvalidSoundId) WwiseLogger.LogMessage(WwiseLogger.LogLevel.Warning, string.Format("Invalid soundId.", soundId)); return; var result = AkSoundEngine.ExecuteActionOnEvent(soundId, AkActionOnEventType.AkActionOnEventType_Resume, soundSource); if (result != AKRESULT.AK_Success) WwiseLogger.LogMessage(WwiseLogger.LogLevel.Warning, string.Format("Resume wwise event with id <0> failed.", soundId), result); else WwiseLogger.LogMessage(WwiseLogger.LogLevel.Normal, string.Format("Resume event with id <0>.", soundId)); /// <summary> /// Stop Audio. /// </summary> /// <param name="soundId">Wwise event id, defined in <see cref="AK.EVENTS"/></param> /// <param name="soundSource">发声源</param> /// <param name="transitionDuration">停止所需时间,单位为毫秒(ms)</param> /// <param name="curveInterpolation">音量变化曲线</param> public void Stop(uint soundId, GameObject soundSource = null, int transitionDuration = 0, AkCurveInterpolation curveInterpolation = AkCurveInterpolation.AkCurveInterpolation_Linear) var result = AkSoundEngine.ExecuteActionOnEvent(soundId, AkActionOnEventType.AkActionOnEventType_Stop, soundSource == null ? gameObject : soundSource, transitionDuration, curveInterpolation); if (result != AKRESULT.AK_Success) WwiseLogger.LogMessage(WwiseLogger.LogLevel.Warning, string.Format("Stop event with id <0> failed.", soundId), result); return;
需要注意的是,经过试验,wwise的暂停和恢复走的是计数机制,暂停多少次,就需要恢复多少次才能够正常恢复。
- 优点:非常灵活,无需定义大量时间
- 缺点:基于计数的暂停和恢复在复杂的游戏业务里可能会难以正确控制
如何在 C# 中暂停和恢复音频
【中文标题】如何在 C# 中暂停和恢复音频【英文标题】:how to pause and resume audio in c# 【发布时间】:2015-08-11 14:27:32 【问题描述】:我正在开发 wpf 应用程序。我想暂停和恢复音频,但歌曲从头开始播放。
//c# code
System.Media.SoundPlayer sp = new System.Media.SoundPlayer(@"D:\Intro.wav");
private void play_Click(object sender, EventArgs e)
sp.Play();
play_btn.Enabled = false;
stop_btn.Enabled = true;
private void stop_Click(object sender, EventArgs e)
sp.Stop();
stop_btn.Enabled = false;
play_btn.Enabled = true;
【问题讨论】:
被问到before。 但是没有得到满意的回答,所以还需要回答。 @goobering,已回答,但回答根本不被接受(经常发生)。我的评论是说“使用搜索”的一种外交方式。 SoundPlayer API 不支持暂停。您是否尝试过操作 Stream 对象?如果您不能选择使用 MediaElement,请将其添加到问题中。现在问题的格式是重复的,因为链接的问题确实有一个使用不同 API 的答案。 【参考方案1】:使用System.Windows.Controls.MediaElement
而不是System.Media.SoundPlayer
。它有一个Pause
函数。
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="320*"/>
<RowDefinition Height="50*"/>
</Grid.RowDefinitions>
<MediaElement x:Name="MediaPlayer" Grid.RowSpan="1" LoadedBehavior="Manual"/>
<StackPanel Orientation="Horizontal" Grid.Row="1" HorizontalAlignment="Center">
<Button x:Name="btnPlay" Content="Play" Click="btnPlay_Click" Width="50" Height="25" Margin="5"/>
<Button x:Name="btnStop" Content="Stop" Click="btnStop_Click" Width="50" Height="25" Margin="5"/>
<Button x:Name="btnMoveBack" Content="Back" Click="btnMoveBack_Click" Width="50" Height="25" Margin="5"/>
<Button x:Name="btnMoveForward" Content="Forward" Click="btnMoveForward_Click" Width="50" Height="25" Margin="5"/>
</StackPanel>
</Grid>
private void IsPlaying(bool flag)
btnPlay.IsEnabled = flag;
btnStop.IsEnabled = flag;
btnMoveBack.IsEnabled = flag;
btnMoveForward.IsEnabled = flag;
private void btnPlay_Click(object sender, RoutedEventArgs e)
IsPlaying(true);
if (btnPlay.Content.ToString() == "Play")
MediaPlayer.Play();
btnPlay.Content = "Pause";
else
MediaPlayer.Pause();
btnPlay.Content = "Play";
private void btnStop_Click(object sender, RoutedEventArgs e)
MediaPlayer.Pause();
btnPlay.Content = "Play";
IsPlaying(false);
btnPlay.IsEnabled = true;
private void btnMoveBack_Click(object sender, RoutedEventArgs e)
MediaPlayer.Position -= TimeSpan.FromSeconds(10);
private void btnMoveForward_Click(object sender, RoutedEventArgs e)
MediaPlayer.Position += TimeSpan.FromSeconds(10);
【讨论】:
代码更可能取自here。【参考方案2】:Soundplayer 不支持暂停和恢复。您可以改用 WPF MediaElement。
如果您必须使用 Soundplayer,您可以每秒使用静音歌曲启动一个新线程。之后,您必须在暂停方法中将响亮的静音。在 Resume Method 中,您必须检查哪个线程处于最佳时间。
但我认为这将是最可怕的解决方案。
干杯
【讨论】:
那将是一个可怕的解决方案。如果音轨是 10 分钟长,你最终会得到 36000 个线程!以上是关于UnityWwise具体某一音频的暂停恢复和终止播放的主要内容,如果未能解决你的问题,请参考以下文章