我已经编写了this source的代码,但是当我想循环播放视频时,它会稍微冻结一半左右。当我在互联网上搜索时,我在Here中看到了一些指南,例如制作一个帖子,并在那里做所有事情。我也写了一个Thread,但是当我编译项目时,它是一样的。有人还告诉我你的问题是你正在使用_videoThread.Join()。但当我删除它时,视频播放速度很慢,我不知道为什么,这是我的代码,如果有人帮助我,我将不胜感激:
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using System.Threading;
namespace VideoTest2
{
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
Thread _videoThread;
Rectangle screen;
Video _video;
Video _video2;
VideoPlayer _videoPlayer;
Texture2D _videoTexture;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
protected override void Initialize()
{
base.Initialize();
}
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
_video = Content.Load<Video>("My Movie");
_video2 = Content.Load<Video>("My Movie2");
}
protected override void UnloadContent()
{
// TODO: Unload any non ContentManager content here
_videoThread.Abort();
_videoPlayer.Dispose();
}
private void DoVideoThread()
{
if (_videoPlayer == null)
{
_videoPlayer = new VideoPlayer();
_videoPlayer.Play(_video);
}
if (_videoPlayer.State != MediaState.Stopped)
{
_videoTexture = _videoPlayer.GetTexture();
}
else //(_videoPlayer.State == MediaState.Stopped)
{
_videoPlayer.Play(_video);
}
}
protected override void Update(GameTime gameTime)
{
if (Keyboard.GetState().IsKeyDown(Microsoft.Xna.Framework.Input.Keys.Escape))
this.Exit();
_videoThread = new Thread(DoVideoThread) { IsBackground = true, Name = "VideoThread" };
_videoThread.Start();
_videoThread.Join();
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
// Drawing to the rectangle will stretch the
// video to fill the screen
screen = new Rectangle(GraphicsDevice.Viewport.X,
GraphicsDevice.Viewport.Y,
GraphicsDevice.Viewport.Width,
GraphicsDevice.Viewport.Height);
// Draw the video, if we have a texture to draw.
if (_videoTexture != null)
{
spriteBatch.Begin();
spriteBatch.Draw(_videoTexture, screen, Color.White);
spriteBatch.End();
}
base.Draw(gameTime);
}
}
}
由于
答案 0 :(得分:2)
我还为此编写了一个Thread但是当我编译项目时,它是一样的。有人还告诉我你的问题是你正在使用_videoThread.Join()。但当我删除它时,视频播放速度很慢,我不知道为什么
当_videoThread.Join()
存在时,它会阻塞主线程(在本例中为XNA游戏循环线程),直到线程退出。
但是当我删除它时,视频播放速度很慢,我不知道为什么
那是因为当您删除_videoThread.Join()
一件好事 - 主UI线程不再等待子线程完成,所以理论上你的游戏不应该冻结
< / LI> 坏事 - 因为当您在Update()
期间生成线程时,不进行任何检查以查看线程是否正在运行而是生成新线程每一帧!
要解决您的问题,请更改此代码:
protected override void Update(GameTime gameTime)
{
if (Keyboard.GetState().IsKeyDown(Microsoft.Xna.Framework.Input.Keys.Escape))
this.Exit();
_videoThread = new Thread(DoVideoThread) { IsBackground = true, Name = "VideoThread" };
_videoThread.Start();
_videoThread.Join();
base.Update(gameTime);
}
...为:
protected override void Update(GameTime gameTime)
{
if (Keyboard.GetState().IsKeyDown(Microsoft.Xna.Framework.Input.Keys.Escape))
{
this.Exit();
}
if (_videoThread != null &&
!_videoThread.IsAlive &&
_videoPlayer.State == MediaState.Stopped)
{
_videoThread = new Thread(DoVideoThread) { IsBackground = true, Name = "VideoThread" };
_videoThread.Start();
}
// Get the current video frame as a texture for this frame
if (_videoPlayer.State != MediaState.Stopped)
{
_videoTexture = _videoPlayer.GetTexture();
}
base.Update(gameTime);
}
现在只会生成一个线程来播放视频。
我并不完全相信您需要一个仅用于媒体控制的线程,我们不会对音频执行此操作,并且您不负责解码视频。
答案 1 :(得分:0)
I modified it a bit, then its working fine, please do try like this below
protected override void Update(GameTime gameTime) {
if (_videoThread == null &&
_videoPlayer.State == MediaState.Stopped)
{
_videoThread = new Thread(DoVideoThread) { IsBackground = true, Name = "VideoThread" };
_videoThread.Start();
}
}// modified draw
protected override void Draw(GameTime gameTime)
{ if (_videoThread != null && !_videoThread.IsAlive && _videoPlayer.State == MediaState.Stopped)
{ _videoThread = new Thread(DoVideoThread) { IsBackground = true, Name = "VideoThread" };
_videoThread.Start();}
// Draw the video, if we have a texture to draw.
if (_videoTexture != null)
{
spriteBatch.Begin();
spriteBatch.Draw(_videoTexture, screen, Color.White);
spriteBatch.End();
}
base.Draw(gameTime);
}
}
}
Thanks