XNA 可变音频速度
我正在尝试将外部音频文件与以可变帧速率播放的视频同步。当视频缓慢播放时,音频应该减慢,当加速时,音频应该加快。
我已经解决了视频播放问题,但音频仍然困扰着我。如何以这种方式同步视频和音频?
我确切地知道在任何时刻正在播放哪个视频帧,所以我希望以某种方式使用这些信息来改变音频速度。但是,还是很困惑,不知道该怎么做。
在我的情况下,声音是否失真并不重要,它只需要始终与视频保持同步即可。视频播放速度由用户实时控制,无法提前确定。
I'm trying to sync an external audio file with a video that is played back at a variable framerate. When the video plays slowly, the audio should slow down, and when speeding up it should speed up.
I got the video playback sorted out, but the audio is still troubling me. How to sync the video to the audio this way?
I know exactly which video frame is playing at any moment, so I was hoping to use this information somehow to change the audio speed. But, still puzzled about how to.
It does not matter if the sound is distorted in my case, it just needs to keep in sync with video at all times. The video playback speed is controlled in realtime by the user, and cannot be determined in advance.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
注意:我假设您使用的是 Visual Studio 2008/2010,但如果您也使用 XNA Game Studio,则答案应该适用。
您可以使用FMOD库来播放您的音频,它会完全满足您的需要。
初始设置
您需要下载 Windows 32 位 API。安装后,从那里转到“C:\Program Files(x86)\FMOD Sound System\FMOD Programmers API Win32\API”,复制 fmodex.dll 和 fmodexL .dll 到您的项目目录中,以及 Csharp 文件夹的内容。
在您的项目中,通过在解决方案资源管理器中右键单击项目,然后单击“添加 > 现有项目...”,将 2 个 DLL 文件和 4 个类文件添加到您的项目中;将它们添加到项目后,在解决方案资源管理器中选择这些文件,并确保它们的“复制到输出目录”属性设置为“始终复制”。您现在已准备好使用 FMOD 系统。
使用FMOD
在主类中,添加以下 using 语句
using FMOD;
,并添加以下变量:private FMOD.System sndSystem;
私有 FMOD.Channel sndChannel = new FMOD.Channel();
private FMOD.Sound sndSound = new FMOD.Sound();
在 LoadContent() 内
FMOD.Factory.Create_System(ref sndSystem);
sndSystem.Init(1, INITFLAGS.NORMAL, (IntPtr)null);
sndSystem.CreateSound("**<音频路径>**", MODE.HARDWARE, ref sndSound);
现在,无论您想在何处开始播放声音,您只需输入:
sndSystem .PlaySound(CHANNELINDEX.FREE, sndSound, false, ref sndChannel);
并停止它:
sndChannel.stop();
出于您的目的,当音频与视频一起播放时,您可以确定此时视频的速度有多快(1.0f 为正常速度,2.0f 为双速,0.5f 为半速等),并将该值传递给 sndSound.setMusicSpeed(
sndSound.setMusicSpeed(
sndSound.setMusicSpeed(
sndSound.setMusicSpeed(
sndSound.setMusicSpeed);速度值>);
。NOTE: I'm assuming you're using Visual Studio 2008/2010, but the answer should apply if you're using XNA Game Studio as well.
You could use the FMOD library to play your audio, it'll do exactly what you need.
Initial Setup
You'd download the windows 32bit API. From there, after you've installed it, you'd go to "C:\Program Files(x86)\FMOD Sound System\FMOD Programmers API Win32\API", copy fmodex.dll and fmodexL.dll into your project directory, along with the contents of the Csharp folder there as well.
From your project, add the 2 DLL files, and the 4 class files into your project by right clicking on it in the solution explorer, and clicking "Add > Existing Item..."; once these are added to your project, select those files in the solution explorer, and make sure their "Copy to output Directory" property is set to "Copy Always". You're now ready to use the FMOD system.
Using FMOD
Inside your main class, add the following using statement
using FMOD;
, and add the following variables:private FMOD.System sndSystem;
private FMOD.Channel sndChannel = new FMOD.Channel();
private FMOD.Sound sndSound = new FMOD.Sound();
Within your LoadContent()
FMOD.Factory.Create_System(ref sndSystem);
sndSystem.Init(1, INITFLAGS.NORMAL, (IntPtr)null);
sndSystem.CreateSound("**<Path To Your Audio>**", MODE.HARDWARE, ref sndSound);
Now whereever you want to start to play your sound, you just put in:
sndSystem.PlaySound(CHANNELINDEX.FREE, sndSound, false, ref sndChannel);
and to stop it:
sndChannel.stop();
For your purposes, while the audio was playing with the video, you'd determine how fast the video was going at that point, (1.0f for normal speed, 2.0f for double speed, .5f for half speed, etc) and pass that value to the
sndSound.setMusicSpeed(<speedvalue>);
.您的请求的成功之路可能是漫长而艰巨的。似乎可以执行您所要求的操作,但由于 MediaPlayer 类的 PlayPosition 属性是只读的,因此相当困难。这里一个链接可能会帮助激发您的灵感。
The road to success for your request is potentially long and arduous. It seems that it's possible to do what you're asking, but because the PlayPosition property of the MediaPlayer class is readonly it's rather difficult. Here is a link that may help inspire you.