MediaElement不在WPF中的Close()方法上释放文件 [英] MediaElement not releasing the file on its Close() method in WPF

查看:65
本文介绍了MediaElement不在WPF中的Close()方法上释放文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您好,



我需要在系统上播放同一媒体文件的多个实例,并在删除/关闭最后一个实例时删除该文件。

没有涉及UI,媒体在某些触发器上播放/停止。

我能够使用MediaElement播放文件,我能够收听同一首歌曲并行并单独停止它们。



删除媒体文件时出现问题。

MediaElement不会在MediaElement上释放文件流。关闭()并且不删除文件。只有在应用程序关闭后它才会被删除。

我觉得它是MediaElement.Close()和File.Delete()之间的时间问题,因为它间歇性地发生。

我想通过删除未使用的文件来删除文件以创建内存。

可以通过创建至少2个MediaElement来重新定义,其中Source(Uri)引用相同的媒体文件。

播放MediaElement后,我们关闭媒体并删除文件。有时会删除文件,有时则不会。



感谢对MediaElement锁定的文件问题的任何想法,并且无法立即删除。



提前致谢!

解决方案

需求发生了变化,我没有使用MediaElement。我正在使用NAudio库来播放媒体文件,因为要求是通过ASIO驱动程序播放媒体文件。

但是,我尝试使用NAudio编写上述问题并且它似乎正在工作。 />
请查看以下示例代码。它不是经过测试的代码。



使用System;< br /> 
使用System.Collections.Generic;< br />
使用System.Linq;< br />
使用NAudio.Wave;< br />
使用System.Windows.Threading;< br />
使用System.Diagnostics;< br />
使用System.IO;< br />
< br />
命名空间NAudioConsoleDemo< br />
{< br />
class Program< br />
{< br />
private static List< iwaveplayer> _mediaPlayers = new List< iwaveplayer>(2);< br />
private static List< wavestream> _mediaStreams = new List< wavestream>(2);< br />
< br />
private static string _fileName1 = @D:\ Audio Files \ Song skip \ 911。 wav;< br />
static秒表_watch = new秒表();< br />
< br />
static void Main(string [] args)< br />
{< br />
Console.WriteLine(已开始);< br />
< br />
Play();< br />
< br />
Console.ReadLine();< br />
}< br />
< br />
private static void Play()< br />
{< br />
for(int index = 0; index< 2; index ++)< br />
{< ; br />
_mediaPlayers.Add(CreatePlayer());< br />
if(_mediaPlayers [index]!= null)< br />
{< br / >
_mediaPlayers [index] .PlaybackStopped + = MediaPlayerOnPlaybackStopped;< br />
}< br />
_mediaStreams.Add(CreateMediaStream(_fileName1));< br />
}< br />
< br />
int counter = 0;< br />
< br />
//播放所有玩家< br />
foreach(varmediaPlayer in _mediaPlayers)< br />
{< br />
if(_mediaStreams [counter]!= null)< br />
{< br />
mediaPlayer.Init(_mediaStreams [counter]);< br />
mediaPlayer.Play();< br />
_watch.Start();< br />
Console.WriteLine([{0}]媒体播放...,计数器) ;< br />
System.Threading.Thread.Sleep(1000);< br />
}< br />
counter ++;< br />
}< br />
}< br />
< br />
///< summary>< br />
///创建要在此设备上播放媒体的播放器< br />
///< / summary>< br />
///<返回>播放器以播放媒体< / returns>< ; br />
私有静态IWavePlayer CreatePlayer()< br />
{< br />
返回新的WaveOutEvent();< br />
}< ; br />
私有静态对象lockObj = new object();< br />
& lt; br />
///< summary>< br />
///当媒体停止播放时调用< br />
///< / summary> < br />
///< param name =sender> sender< / param>< br />
///< param name =e>已停止事件参数< / param>< br />
protected static void MediaPlayerOnPlaybackStopped(object sender,StoppedEventArgs e)< br />
{< br />
_watch.Stop() ;< br />
< br />
var mediaPlayer =发送者为IWavePlayer;< br />
if(mediaPlayer!= null)< br />
{< br />
int index = _mediaPlayers.IndexOf(mediaPlayer);< br />
var mediaStream = _mediaStreams.ElementAt(index);< br />
Dispose (mediaPlayer,mediaStream);< br />
_mediaStreams.RemoveAt(index);< br />
_mediaPlayers.RemoveAt(index);< br />
Console.WriteLine ([{0}] Media Stopped,index);< br />
Console.WriteLine([{0}]总时间:{1},index,_watch.Elaps ed.TotalSeconds);< br />
}< br />
< br />
if(_mediaPlayers.Count == 0)< br />
{< br />
//删除媒体文件< br />
File.Delete(_fileName1);< br />
Console.WriteLine(媒体已删除) ;< br />
}< br />
}< br />
< br />
protected static WaveStream CreateMediaStream(string filePath)< br />
{< br />
返回新的WaveFileReader(filePath);< br />
}< br />
< br />
private static void Dispose(IWavePlayer mediaPlayer,WaveStream mediaStream)< br />
{< br />
if(mediaPlayer!= null)< br />
{< br />
mediaPlayer.Stop();< br />
mediaPlayer.Dispose();< br />
mediaPlayer = null;< br />
}< br />
if(mediaStream!= null)< br />
{< br />
mediaStream.Dispose();< br />
mediaStream = null;< br />
}< br />
}< br />
}< ; br />
}< / wavestream>< / wavestream>< / iwaveplayer>< / iwaveplayer>









您需要将NAudio.dll包含在您的项目中才能使用它。

希望这有助于!!!


Hello,

I need to play multiple instances of a same media file on a system and delete the file whenever last instance is deleted/closed.
There is no UI involved in it and media is played/stopped on some triggers.
I have been able to play the file using MediaElement and I am able to listen to same song in parallel and stop them individually.

The issue occured while deletion of the media file.
MediaElement doesn't release the filestream on MediaElement.Close() and the file is not deleted. It gets deleted only after application is closed.
I feel it to be a timing issue between MediaElement.Close() and File.Delete() as it happens intermittently.
I wanted to delete the file in order to create memory by deleting unused file(s).
It can be reporduced by creating atleast 2 MediaElement whose Source(Uri) refer to same media file.
After playing both the MediaElement, we close the media and delete the file(s). Sometimes it deletes the file, sometime doesn't.

Appreciate any thoughts on this issue of file being locked by the MediaElement and unable to delete instantly.

Thanks in advance!

解决方案

There was a change in requirement and I am not using the MediaElement. I am using NAudio library to play the media files as the requirement is to play media files through ASIO driver.
However, I tried to code the above issue with NAudio and it seems to be working.
Please have a look at the below sample code. It's not a tested code.

using System;<br />
using System.Collections.Generic;<br />
using System.Linq;<br />
using NAudio.Wave;<br />
using System.Windows.Threading;<br />
using System.Diagnostics;<br />
using System.IO;<br />
<br />
namespace NAudioConsoleDemo<br />
{<br />
	class Program<br />
	{<br />
		private static List<iwaveplayer> _mediaPlayers = new List<iwaveplayer>(2);<br />
		private static List<wavestream> _mediaStreams = new List<wavestream>(2);<br />
<br />
		private static string _fileName1 = @"D:\Audio Files\Song skip\911.wav";<br />
		static Stopwatch _watch = new Stopwatch();<br />
<br />
		static void Main(string[] args)<br />
		{			<br />
			Console.WriteLine("Started");<br />
			<br />
			Play();<br />
<br />
			Console.ReadLine();<br />
		}<br />
<br />
		private static void Play()<br />
		{<br />
			for(int index = 0; index < 2; index++)<br />
			{<br />
				_mediaPlayers.Add(CreatePlayer());<br />
				if (_mediaPlayers[index] != null)<br />
				{<br />
					_mediaPlayers[index].PlaybackStopped += MediaPlayerOnPlaybackStopped;<br />
				}<br />
				_mediaStreams.Add(CreateMediaStream(_fileName1));<br />
			}<br />
<br />
			int counter = 0;<br />
<br />
			// Play all the players<br />
			foreach (var mediaPlayer in _mediaPlayers)<br />
			{<br />
				if (_mediaStreams[counter] != null)<br />
				{<br />
					mediaPlayer.Init(_mediaStreams[counter]);<br />
				    mediaPlayer.Play();<br />
					_watch.Start();<br />
					Console.WriteLine("[{0}] Media Playing... ", counter);<br />
					System.Threading.Thread.Sleep(1000);<br />
				}<br />
				counter++;<br />
			}<br />
		}<br />
<br />
		/// <summary><br />
		/// Creates a player to play media on this device<br />
		/// </summary><br />
		/// <returns>player to play the media</returns><br />
		private static IWavePlayer CreatePlayer()<br />
		{<br />
			return new WaveOutEvent();<br />
		}<br />
		private static object lockObj = new object();<br />
<br />
		/// <summary><br />
		/// Called when media has stopped playing<br />
		/// </summary><br />
		/// <param name="sender">sender</param><br />
		/// <param name="e">Stopped Event arguments</param><br />
		protected static void MediaPlayerOnPlaybackStopped(object sender, StoppedEventArgs e)<br />
		{<br />
			_watch.Stop();<br />
			<br />
			var mediaPlayer = sender as IWavePlayer;<br />
			if (mediaPlayer != null)<br />
			{<br />
				int index = _mediaPlayers.IndexOf(mediaPlayer);<br />
				var mediaStream = _mediaStreams.ElementAt(index);<br />
				Dispose(mediaPlayer, mediaStream);<br />
				_mediaStreams.RemoveAt(index);<br />
				_mediaPlayers.RemoveAt(index);<br />
				Console.WriteLine("[{0}] Media Stopped", index);<br />
				Console.WriteLine("[{0}] Total Time: {1}", index, _watch.Elapsed.TotalSeconds);<br />
			}		<br />
<br />
			if (_mediaPlayers.Count == 0)<br />
			{<br />
				// Delete the media File<br />
				File.Delete(_fileName1);<br />
				Console.WriteLine("Media Deleted");<br />
			}<br />
		}<br />
<br />
		protected static WaveStream CreateMediaStream(string filePath)<br />
		{<br />
			return new WaveFileReader(filePath);<br />
		}<br />
<br />
		private static void Dispose(IWavePlayer mediaPlayer, WaveStream mediaStream)<br />
		{<br />
			if (mediaPlayer != null)<br />
			{<br />
				mediaPlayer.Stop();<br />
				mediaPlayer.Dispose();<br />
				mediaPlayer = null;<br />
			}<br />
			if (mediaStream != null)<br />
			{<br />
				mediaStream.Dispose();<br />
				mediaStream = null;<br />
			}<br />
		}<br />
	}<br />
}</wavestream></wavestream></iwaveplayer></iwaveplayer>





You need to include NAudio.dll to your project in order to use it.
Hope this helps!!!


这篇关于MediaElement不在WPF中的Close()方法上释放文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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