Game Development Community

New resource: GUIVideo for TX2D 3.0.0.0

by Jason Cahill · in Torque X 2D · 07/19/2009 (11:30 am) · 27 replies

Here's a piece of engine code I developed for myself that I thought I'd share with the community. It allows you to add WMV-based video to your TorqueX project, utilizing the awesome new support for video in XNA 3.1. Enjoy!

www.garagegames.com/community/resources/view/17871
Page «Previous 1 2
#1
07/19/2009 (11:38 am)
Hey Jason,
Really awesome stuff! I added the resource to the Community Links section.

Brian
#2
07/19/2009 (12:36 pm)
Looks very cool. Two things:

  1. If I understand it rightly, I would specify the video I want to play by using the Bitmap property?
  2. Given that TorqueX has no GUI editor, I'm not real familiar with working with a .gui file and so would more than likely create them in code. Did you have it set so that the menuscreen is directly below the GUICanvas, and then the GUIVideo is a child of that?

***EDIT*** One more thing: should _defaultTypeMap also be set for VideoMaterial, or does that not really matter?

Also, it looks like you based it on the GUIBitmap control, so I assume there is a lot in there that is not strictly necessary. I haven't read through completely the documentation on VideoPlayer and Video, but it seems we would just need to use the Content Manager to load the video, then create the video player to control it. I should say, I'm not knocking your code, just trying to wrap my head around what's all going on in there.
#3
07/19/2009 (1:26 pm)
OK, never mind my confusion on the Bitmap parts. I see now that calling VideoPlayer.Play does not actually render anything and that I still have to grab a texture of the current frame and render manually. Kind of pain in the butt, but oh well.

It begs the question, then, what about the audio of the movie? Or does this, then, only work as a silent movie?
#4
07/19/2009 (1:48 pm)
You can create these either in a .ui file (which is just an XML file) or in code. The GUIVideo control is just another GUIControl and as such can be a child of either the GUICanvas or any other GUIControl.

I based my control on the GUIBitmap, but removed the pieces that were irrelevant. Everything in the GUIVideo and GUIVideoStyle classes are essential. I suppose I could have renamed the Bitmap property to Video, but it didn't seem strictly necessary. Basically, the Bitmap property takes the name of a string of your WMV file. Under the covers it creates a VideoMaterial which does the actual heavy lifting.

BTW, you should be able to new up a VideoMaterial for use on any T2D object. In other words, this is also useful for making a Video object playing back on a T2DStaticSprite. The possibilities will be endless with this thing. I have been strictly focused on GUI stuff lately, so I haven't had a chance to have fun and experiment with sprites using video textures, but it should "just work."

Re: audio: basically, XNA takes care of audio and video playback almost automatically. You just need to call VideoPlayer.GetTexture() in each draw call. This ensures lipsyncing is taken care of for you automatically.

In my sample, I took 30 seconds of the opening of a episode of Battlestar Galactica and it plays audio and video perfectly. Notice the IsLooping property as well if you want to have your video repeat at the end auotmatically.

You are required to have an audio stream with your video, but if you want a silent video, you just need a silent audio stream.

Hope that helps. If you have additional feedback, questions, or suggestions, I'm happy to help and even update the code as necessary.
#5
07/19/2009 (4:17 pm)
Cool, I tried it out with the TorqueX 2D Starter Game and it works nicely.

For those want to test it out easily:

  1. Create new TorqueX 2D (3.0) Starter Game.
  2. ***EDIT*** Torque 2D 3.1 is now available for download.
  3. Upgrade the solution (to 3.1) if needed.
  4. If they don't yet exist, create cs files from Jason's resource as GUIVideo.cs and VideoMaterial.cs.
  5. Right-click the correct folders in the Torque project and add the existing files GUIVideo and VideoMaterial.
  6. Add the 2 lines to TorqueSceneData, as per Jason's instructions.
  7. Add the existing WMV file to the Game Content project.
  8. Add the following code just after the scene-loading line in BeginRun():
    GUIVideo guivid = new GUIVideo();
    guivid.Style = new GUIVideoStyle();
    guivid.Bitmap = @"data\video\BillO";
    
    GUICanvas.Instance.SetContentControl(guivid);
    guivid.Play();
    Of course, that's assuming the video is in a data folder called "video".

***EDIT*** I used a program called Any Video Converter to convert to WMV with good results. I don't have a vested interest in it, just that it worked well, especially since my original was FLV.

***EDIT*** I see others noticed the missing backslashes, too.
#6
07/19/2009 (4:50 pm)
Quote:P.S. Anyone else notice that backslashes disappear when you post to these forums? I have to always go back and edit my post to add them back in. I don't know if it is just me or what. Incidentally, I'm using FireFox 3.0.11.

Seems like its a known issue that Jason already posted a thread on.

#7
07/19/2009 (6:14 pm)
Glad to hear it--thought I might be going crazy.
#8
07/19/2009 (8:14 pm)
@Scott: Thanks for tutorializing my example even more -- and vetting that it works on someone else's deployment! :-)
#9
07/26/2009 (3:18 pm)
Hi, I posted this in the community Links section but wanted to post it here as I'm not sure if that section works quite like a forum. In

A few things.

First of thanks for uploading this resource. It saved me tons of time and is implemented 100 times better then I would have done so myself.

A few question for you.

I created a GuiMainMenu class that inherits from GUIVideo

In order to unload the video from memory I'm assuming I can just call this.Stop();
Then Set my GuiMainMenu to null?

The reason I ask is I found that the video kept playing (I could hear it) even after setting the file to null. So I assume a reference is kept in the code somewhere.

Just wanted to verify that calling stop will free up the memory.


Also on the Xbox though I'm having 2 issues.

1)It dosn't play the video. On Pc the video plays fine but on the xbox I just get a black screen when the video would play

2) I can't exit my game on the xbox it just locks up. Having my GUIMainMenu inherit from GUIBitmap and switching out the syle and bitmap calls fixes this, So I know it's something with how I'm implementing the video. (again everything works fine on pc)

Here is the seemingly relevant parts of my code
class GuiMainMenu: GUIVideo, IGUIScreen
    {
public GuiMainMenu()
        {
//lets try making a video
            VideoStyle = new GUIVideoStyle();
            VideoStyle.SizeToBitmap = false;
            VideoStyle.PreserveAspectRatio = false;

            Name = "GuiMainMenu";
            Style = VideoStyle;
            Bitmap = @"data\video\MainMenu";
            this.Play();
            Size = new Vector2(1280, 720);
            OnGUIWake = OnMainScreenWake;
        }

case 2:
                                    this.Stop();
                                    Game.Instance.Exit();
                                    break;

Thanks for any help!

#10
07/26/2009 (3:58 pm)
Hi Matthew,

I just submitted a 23 page intro guide to the Torque X GUI system. That should hopefully help folks out a lot. On your specific solution, the GUIVideo control was designed to be a single control amongst other controls on the GUICanvas, as opposed to being derived from. I suspect a bunch of the issues you are seeing may stem from that.

On the video itself: Windows will play way more kinds than the Xbox. There are strict requirements on what the Xbox will play. Your video MUST be a WMV9 CBR (constant bit rate) video and MUST include both an audio and video stream.
#11
07/26/2009 (7:05 pm)
Thanks Jason. I'll check out that guide :). It will be great to see a good GUI guide. Will it be posted in the Resource section?

I'll create the video as a control on my MainMenu and see if that does it :).
#12
07/26/2009 (7:11 pm)
I sent it to Michael, per this thread (http://www.garagegames.com/community/forums/viewthread/97973). I think Michael was going to post it to TDN (I don't seem to have enough permissions), but we shall see.
#13
09/07/2009 (12:31 pm)
Hi,

I started working with this again. Downloaded the Video Playback sample from Microsoft to be sure my video file wasn't causing the problems.

No luck. :(

Everything works great on the pc but doesn't show up on xbox and keeps the game from exiting.

I even tried loading a video as scott did above with this code
GUIVideo guivid = new GUIVideo();  
   guivid.Style = new GUIVideoStyle();  
   guivid.Bitmap = @"data/video/video";  
     
   GUICanvas.Instance.SetContentControl(guivid);  
   guivid.Play();

It doesn't show up at all on the xbox works 100% on pc.

Anyone got this to work on the xbox?
#14
09/07/2009 (7:54 pm)
No, I tried getting it to work on the XBox, but couldn't do it. I had to resort to hacking it in using a raw XNA solution.

In a special class that I use. OnLevelLoad() is called when the titlescreen level is loaded:
public class titlescreen
    {
        static public VideoPlayer _videoPlayer = null;
        static public SpriteBatch _spriteBatch = null;
        static public Video _video = null;
        public static bool _firstRun = true;

        static public void StopVideo()
        {
            _spriteBatch.Dispose();
            _videoPlayer.Stop();
            _videoPlayer.Dispose();
            _video = null;
            _videoPlayer = null;
            _spriteBatch = null;
            Game.Instance.DoCutsceneHack = false;
            Game.Instance.CutsceneHack = null;
        }

        static public void DoVideoHack()
        {
            if (_firstRun)
            {
                _firstRun = false;
                _videoPlayer = new VideoPlayer();
                _spriteBatch = new SpriteBatch(Game.Instance.Engine.GraphicsDevice);
                _video = Game.Instance.Content.Load<Video>(@"datamoviesintro");
                _videoPlayer.Play(_video);
            }

            Game.Instance.GraphicsDevice.Clear(Color.Black);
            Texture2D _texture = _videoPlayer.GetTexture();

            _spriteBatch.Begin();
            int width = (int)(Game.Instance.Window.ClientBounds.Height * 1.5f);
            int offsetX = (Game.Instance.Window.ClientBounds.Width - width) / 2;
            //int offsetY = (Game.Instance.Window.ClientBounds.Height - _texture.Height) / 2;
            _spriteBatch.Draw(_texture, new Rectangle(offsetX, 0, width, Game.Instance.Window.ClientBounds.Height), Color.White);
            _spriteBatch.End();

            if (_videoPlayer.State == MediaState.Stopped)
            {
                StopVideo();
                SoundManager.Instance.PlaySound("music_title", "titlescreen");
                //Game.Instance.LoadLevel("titlescreen");
            }
        }

        static public void OnLevelLoad()
        {
            _firstRun = true;

            Game.Instance.Camera.CameraStyle = LEVELCAMERA.MANUALCONTROL;
            Game.Instance.Camera.SetPosition(new Vector2(0.0f, 0.0f), 0.1f, GarageGames.Torque.Util.InterpolationMode.Linear);
            Game.Instance.GUI.DisplayBlank();

            Game.Instance.DoCutsceneHack = true;
            Type _t = Type.GetType("Dungeons.scripts.titlescreen");
            MethodInfo _m = _t.GetMethod("DoVideoHack");
            Game.Instance.CutsceneHack = _m;
        }
    }

In Game.cs:
protected override void Draw(GameTime gameTime)
        {
            base.Draw(gameTime);

            if (_doCutsceneHack)
            {
                if (_cutsceneHack != null)
                    _cutsceneHack.Invoke(null, null);
            }
        }

I had originally tried to fix the bug, but I had run out of time, which is where the quick XNA hack came in. I think it is a bug in VideoMaterial's Texture property and the ResourceManager, but I am not sure.

EDIT: The way it works is that it has two properties in the Game class: DoCutsceneHack (bool) and CutsceneHack (MethodInfo). When DoCutsceneHack is true, it will invoke whatever function CutsceneHack points to. So, when I want to play my cutscene, I fill in CutsceneHack (I do that in OnLevelLoad()).
#15
09/08/2009 (12:35 am)
Thanks so much for posting this. I'm going to try to implement your method this week. I'll let you know how it goes.

Ya I couldn't figure out what was wrong with the code either. It's a ton harder to debug when something is xbox specific.

Thanks again!
#16
09/15/2009 (11:19 pm)
Heya, thanks man it worked. I have video on the xbox. :)

#17
09/16/2009 (5:50 pm)
Jason, this is really cool and it works great! Thank you for posting...
Quote:
I grant GarageGames full use of this source code for inclusion in a future release of Torque X.
It's been added to the upcoming Torque X 3.1.4 release so that everyone can tap into this excellent resource!

John K.
#18
09/16/2009 (10:11 pm)
John Jason's code is not working on the xbox far as me and Willam can tell. In fact it doesn't play at all and crashes the xbox when you try to exit the game. (works fine on the pc though)

I could be doing something wrong but if you haven't already you may want to find someone who can verify that it will work on the xbox before adding it to the future release.


#19
09/30/2009 (10:51 pm)
Hi Matthew, just wanted to check in again... I haven't checked the GuiVideo control, but the VideoMaterial is rendering on Xbox 360 as well as Windows after some tweaking. I'll check to find out if the GuiVideo control works as well. I'm pretty sure it will make it into the 3.1.4 release. I personally find the VideoMaterial to be much more interesting when it is embedded within a scene. If I can get a chroma-based translucency working, that would be huge.

www.envygames.com/share/txvideo.jpg

John K.
www.envygames.com
#20
10/03/2009 (12:11 pm)
Awesome. If you get the video control working and wouldn't mind posting the code I'd love to see it. :) thanks!!!
Page «Previous 1 2