Video pausing support; sync video to audio nicer.

This commit is contained in:
Paul Chote
2010-08-14 17:21:54 +12:00
parent 5c8c8d5e6e
commit a569c712f0
5 changed files with 89 additions and 46 deletions

View File

@@ -78,13 +78,25 @@ namespace OpenRA
Play(name, pos); Play(name, pos);
} }
public static void PlayVideoSoundtrack(byte[] raw) public static void PlayVideo(byte[] raw)
{ {
rawSource = LoadSoundRaw(raw); rawSource = LoadSoundRaw(raw);
video = soundEngine.Play2D(rawSource, false, true, float2.Zero, SoundVolume); video = soundEngine.Play2D(rawSource, false, true, float2.Zero, SoundVolume);
} }
public static void StopVideoSoundtrack() public static void PlayVideo()
{
if (video != null)
soundEngine.PauseSound(video, false);
}
public static void PauseVideo()
{
if (video != null)
soundEngine.PauseSound(video, true);
}
public static void StopVideo()
{ {
if (video != null) if (video != null)
soundEngine.StopSound(video); soundEngine.StopSound(video);
@@ -153,6 +165,11 @@ namespace OpenRA
get { return (music != null)? music.SeekPosition : 0; } get { return (music != null)? music.SeekPosition : 0; }
} }
public static float VideoSeekPosition
{
get { return (video != null)? video.SeekPosition : 0; }
}
// Returns true if it played a phrase // Returns true if it played a phrase
public static bool PlayVoice(string phrase, Actor voicedUnit) public static bool PlayVoice(string phrase, Actor voicedUnit)
{ {
@@ -412,8 +429,8 @@ namespace OpenRA
get get
{ {
float pos; float pos;
Al.alGetSourcef(source, Al.AL_SEC_OFFSET, out pos); Al.alGetSourcef(source, Al.AL_SAMPLE_OFFSET, out pos);
return pos; return pos/22050f;
} }
} }
} }

View File

@@ -21,12 +21,21 @@ namespace OpenRA.Widgets.Delegates
{ {
var bg = Widget.RootWidget.GetWidget("VIDEOPLAYER_MENU"); var bg = Widget.RootWidget.GetWidget("VIDEOPLAYER_MENU");
var player = bg.GetWidget<VqaPlayerWidget>("VIDEOPLAYER"); var player = bg.GetWidget<VqaPlayerWidget>("VIDEOPLAYER");
bg.GetWidget("BUTTON_PLAY").OnMouseUp = mi =>
var pp = bg.GetWidget("BUTTON_PLAYPAUSE");
pp.OnMouseUp = mi =>
{ {
if (player.Paused)
player.Play(); player.Play();
else
player.Pause();
return true; return true;
}; };
pp.GetWidget("PLAY").IsVisible = () => player.Paused;
pp.GetWidget("PAUSE").IsVisible = () => !player.Paused;
bg.GetWidget("BUTTON_STOP").OnMouseUp = mi => bg.GetWidget("BUTTON_STOP").OnMouseUp = mi =>
{ {
player.Stop(); player.Stop();

View File

@@ -24,21 +24,24 @@ namespace OpenRA.Widgets
float invLength; float invLength;
float2 videoOrigin, videoSize; float2 videoOrigin, videoSize;
int[,] overlay; int[,] overlay;
public bool DrawOverlay = true; bool stopped;
bool paused;
public bool Paused { get { return paused; } }
public bool DrawOverlay = true;
public void Load(string filename) public void Load(string filename)
{ {
if (filename == cachedVideo) if (filename == cachedVideo)
return; return;
if (playing) stopped = true;
{ paused = true;
playing = false; Sound.StopVideo();
Sound.StopVideoSoundtrack();
}
cachedVideo = filename; cachedVideo = filename;
video = new VqaReader(FileSystem.Open(filename)); video = new VqaReader(FileSystem.Open(filename));
invLength = video.Framerate*1f/video.Frames; invLength = video.Framerate*1f/video.Frames;
var size = Math.Max(video.Width, video.Height); var size = Math.Max(video.Width, video.Height);
@@ -63,16 +66,14 @@ namespace OpenRA.Widgets
overlaySprite.sheet.Texture.SetData(overlay); overlaySprite.sheet.Texture.SetData(overlay);
} }
bool playing = false;
Stopwatch sw = new Stopwatch();
public override void DrawInner(World world) public override void DrawInner(World world)
{ {
if (video == null) if (video == null)
return; return;
if (playing) if (!(stopped || paused))
{ {
var nextFrame = (int)float2.Lerp(0, video.Frames, (float)(sw.ElapsedTime()*invLength)); var nextFrame = (int)float2.Lerp(0, video.Frames, Sound.VideoSeekPosition*invLength);
if (nextFrame > video.Frames) if (nextFrame > video.Frames)
{ {
Stop(); Stop();
@@ -86,6 +87,7 @@ namespace OpenRA.Widgets
videoSprite.sheet.Texture.SetData(video.FrameData); videoSprite.sheet.Texture.SetData(video.FrameData);
} }
} }
Game.Renderer.RgbaSpriteRenderer.DrawSprite(videoSprite, videoOrigin, "chrome", videoSize); Game.Renderer.RgbaSpriteRenderer.DrawSprite(videoSprite, videoOrigin, "chrome", videoSize);
if (DrawOverlay) if (DrawOverlay)
@@ -94,21 +96,34 @@ namespace OpenRA.Widgets
public void Play() public void Play()
{ {
if (playing || video == null) if (video == null)
return; return;
playing = true; if (stopped)
sw.Reset(); Sound.PlayVideo(video.AudioData);
Sound.PlayVideoSoundtrack(video.AudioData); else
Sound.PlayVideo();
stopped = paused = false;
}
public void Pause()
{
if (stopped || paused || video == null)
return;
paused = true;
Sound.PauseVideo();
} }
public void Stop() public void Stop()
{ {
if (!playing || video == null) if (stopped || video == null)
return; return;
playing = false; stopped = true;
Sound.StopVideoSoundtrack(); paused = true;
Sound.StopVideo();
video.Reset(); video.Reset();
videoSprite.sheet.Texture.SetData(video.FrameData); videoSprite.sheet.Texture.SetData(video.FrameData);
} }

View File

@@ -38,21 +38,25 @@ Container@ROOT:
X:2 X:2
Y:0 Y:0
Visible:false Visible:false
Button@BUTTON_PLAY: Button@BUTTON_PLAYPAUSE:
Id:BUTTON_PLAY Id:BUTTON_PLAYPAUSE
X:590 - WIDTH X:600 - WIDTH - 10
Y:460 Y:460
Width:25 Width:25
Height:25 Height:25
Children: Children:
Image@IMAGE_PLAY: Image@PLAY:
Id:IMAGE_PLAY Id:PLAY
X:0
Y:0
Width:25 Width:25
Height:25 Height:25
ImageCollection:music ImageCollection:music
ImageName:play ImageName:play
Image@PAUSE:
Id:PAUSE
Width:25
Height:25
ImageCollection:music
ImageName:pause
Button@BUTTON_STOP: Button@BUTTON_STOP:
Id:BUTTON_STOP Id:BUTTON_STOP
X:610 X:610
@@ -60,10 +64,7 @@ Container@ROOT:
Width:25 Width:25
Height:25 Height:25
Children: Children:
Image@IMAGE_STOP: Image:
Id:IMAGE_STOP
X:0
Y:0
Width:25 Width:25
Height:25 Height:25
ImageCollection:music ImageCollection:music

View File

@@ -38,21 +38,25 @@ Container@ROOT:
X:2 X:2
Y:0 Y:0
Visible:false Visible:false
Button@BUTTON_PLAY: Button@BUTTON_PLAYPAUSE:
Id:BUTTON_PLAY Id:BUTTON_PLAYPAUSE
X:590 - WIDTH X:600 - WIDTH - 10
Y:460 Y:460
Width:25 Width:25
Height:25 Height:25
Children: Children:
Image@IMAGE_PLAY: Image@PLAY:
Id:IMAGE_PLAY Id:PLAY
X:0
Y:0
Width:25 Width:25
Height:25 Height:25
ImageCollection:music ImageCollection:music
ImageName:play ImageName:play
Image@PAUSE:
Id:PAUSE
Width:25
Height:25
ImageCollection:music
ImageName:pause
Button@BUTTON_STOP: Button@BUTTON_STOP:
Id:BUTTON_STOP Id:BUTTON_STOP
X:610 X:610
@@ -60,10 +64,7 @@ Container@ROOT:
Width:25 Width:25
Height:25 Height:25
Children: Children:
Image@IMAGE_STOP: Image:
Id:IMAGE_STOP
X:0
Y:0
Width:25 Width:25
Height:25 Height:25
ImageCollection:music ImageCollection:music