同时下载和播放媒体文件(DirectShowNet) [英] Downloading and playing media file (DirectShowNet) at the same time

查看:111
本文介绍了同时下载和播放媒体文件(DirectShowNet)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

你好,

首先-对不起我的英语:)

我正在尝试编写C#程序,该程序将通过HTTP下载一些媒体文件并同时播放.
就像YouTube Flashplayer一样.
但是我正在使用DirectShowNet库来渲染视频/音频.

在这里,您可能会问自己,为什么这个人不使用"文件源(URL)"过滤器而不是"文件源(异步)"过滤器?我知道会更容易,但是我想管理文件下载过程.

我分别下载文件和单独渲染文件都没有问题.

即使文件未完全下载,DirectShow仍可以呈现文件.实际上,您应该只担心媒体文件的开始"(我想这里有媒体信息).

最后的问题是:
我使用以下代码(在单独的线程中)编写文件:

Hello,

First of all - sorry for my English :)

I''m trying to write C# program which will be download some media file via HTTP and play it at the same time.
It will be something like YouTube flashplayer.
But I''m using DirectShowNet lib to render video/audio.

Here you may ask yourself why this guy doesn''t use "File source (URL)" filter instead of "File Source (Async)" filter? I know it will be easier but I''d like to manage process of file downloading.

I have no problems with file downloading separately and with file rendering separately.

DirectShow can render file even if it wasn''t completely downloaded. Actually you should worry only about "Start" of media file (I guess there are media info).

And the question at last:
I write a file using something like the following code (in separate thread):

Stream strLocal = new FileStream(sTempLocalFilePath,
                                 FileMode.Append,
                                 FileAccess.Write,
                                 FileShare.Read,
                                 downBuffer.Length,
                                 FileOptions.Asynchronous)
while ((bytesSize = strResponse.Read(downBuffer, 0, downBuffer.Length)) > 0)
{
  strLocal.Write(downBuffer, 0, bytesSize);
}


尝试渲染文件时出现错误-该文件已被另一个进程使用.
我关闭Stream strLocal,渲染文件(正在播放),然后尝试再次打开Stream strLocal,但是您知道-文件已被另一个进程使用.

如何写入DirectShow正在使用的文件?

PS:我读过以下文章,但对我没有帮助:-O:
-http://www.java2s.com/Tutorial/CSharp/0300__File-Directory-Stream/AsyncFileStream.htm
-http://www.codeproject.com/KB/threads/asyncFileIO.aspx

感谢您的帮助.

-
Timur


When I try to render the file I have an error - file is used by another process.
I close Stream strLocal,render file (it''s playing) and then I''m trying to open Stream strLocal again but you know - file is used by another process.

How can I write to the file which is using by DirectShow?

PS: I''ve read the following articles but they didn''t help me :-O :
- http://www.java2s.com/Tutorial/CSharp/0300__File-Directory-Stream/AsyncFileStream.htm
- http://www.codeproject.com/KB/threads/asyncFileIO.aspx

Thanks for any help.

--
Timur

推荐答案

如果 DirectShow 已经开始呈现文件,则不太可能写入该文件.反向进行.用FileShare.ReadFileAccess.Write创建文件流,写入前几百个字节,然后将控制权传递给 DirectShow ,后者将打开文件并开始呈现它,然后继续写入文件.

现在,我认为失败的原因是 DirectShow 不会在启用任何共享模式的情况下打开它,因此您尝试打开文件进行写入的尝试将失败.
If DirectShow has already started rendering the file, then it''s unlikely that you can write to it. Do it in reverse. Create the filestream with FileShare.Read and FileAccess.Write, write the first few hundred bytes, then pass control to DirectShow which will then open the file and start rendering it, and then continue writing to your file.

Right now the reason I think it''s failing is that DirectShow will not open it with any share modes enabled, so your attempt to open the file for writing will fail.


Nishant ,谢谢您的回答.您是否认为DirectShow在播放时会阻止文件写入?我相信文件源(异步)"过滤器支持异步I/O.无论如何,这是我如何尝试同时播放和下载文件的示例:

Nishant, thanks for the answer. Do you think that DirectShow blocks file for writing when it''s playing? I believe "File Source (Async.)" filter supports asynchronous I/O. Anyway, here is example how I try to play and download file at the same time:

private void OpenAndPlay(string FileName, bool isURL)
{
.....
	IFileSourceFilter fs = ds_FileSourceFilter as IFileSourceFilter;
	if (isURL)
	{
		Thread thread = new Thread(new ThreadStart(DownloadToPlay));
		sTempLocalFilePath = Path.GetTempFileName();
		thread.Start();
		WaitFile = true;
		_waitFile.WaitOne();
		fs.Load(sTempLocalFilePath, null);
	}
	else
	{
		fs.Load(sFileName, null);
	}
.....
	hr = ds_GraphBuilder.Render(ds_FileSourceFilterOutput);
	DsError.ThrowExceptionForHR(hr);
.....
	_waitFile.Set();//after this "DownloadToPlay" thread back to work but file is blocked for writing
	WaitFile = false;
.....
}

private void DownloadToPlay()
{
	// Create a request to the file we are downloading
	HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(sFileName);
	// Set default authentication for retrieving the file
	webRequest.Credentials = CredentialCache.DefaultCredentials;
	// Retrieve the response from the server
	HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse();
	Stream strResponse;
	// Open the URL for download 
	strResponse = webResponse.GetResponseStream();
	// It will store the current number of bytes we retrieved from the server
	int bytesSize = 0;
	// A buffer for storing and writing the data retrieved from the server
	byte[] downBuffer = new byte[64*1024];
	// Loop through the buffer until the buffer is empty
	Stream strLocal = new FileStream(sTempLocalFilePath, FileMode.Append, FileAccess.Write, FileShare.Read);
	while ((bytesSize = strResponse.Read(downBuffer, 0, downBuffer.Length)) > 0)
	{
		strLocal.Write(downBuffer, 0, bytesSize);
		if (WaitFile == true)
		{
			strLocal.Close();
			_waitFile.Set();
			_waitFile.WaitOne();
			strLocal = new FileStream(sTempLocalFilePath, FileMode.Append, FileAccess.Write, FileShare.Read);
		}
	}
	strLocal.Close();
	strResponse.Close();
	webResponse.Close();
	webRequest.Abort();
}



如果您有任何想法可以继续下载文件,请与我分享.

谢谢.
-
铁木尔



If you have any ideas how I can continue download a file please share with me.

Thanks.
--
Timur


这篇关于同时下载和播放媒体文件(DirectShowNet)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆