c# - Forzar MediaElement a Release Stream después de la reproducción
wpf audio (4)
Estoy creando un control de grabadora de audio, con la funcionalidad de reproducción.
Utilizo el elemento multimedia para reproducir el audio grabado de esta manera:
using (var storage = System.IO.IsolatedStorage.IsolatedStorageFile.GetUserStoreForApplication())
{
using (System.IO.Stream stream = new System.IO.IsolatedStorage.IsolatedStorageFileStream(filePath, System.IO.FileMode.Open, storage))
{
player.SetSource(stream);
}
}
El problema al que me enfrento es que cuando uso el elemento multimedia para reproducir el audio grabado. The Stream está bloqueado en el elemento multimedia. No puedo sobrescribir el archivo ni reproducirlo de nuevo ya que el método SetSource()
arroja una excepción.
¿Hay alguna manera de forzar al elemento multimedia a liberar la transmisión?
Tuve un problema similar con la visualización de imágenes. En un control con una imagen, aparece el mensaje "El archivo está en uso" cada vez que el usuario intenta actualizar la imagen. La solución fue establecer la propiedad BitmapImage.CacheOption
en BitmapCacheOption.OnLoad
:
MSDN dice Establecer CacheOption en BitmapCacheOption.OnLoad si desea cerrar una secuencia utilizada para crear BitmapImage. La opción de caché OnDemand predeterminada conserva el acceso a la transmisión hasta que se necesite la imagen y el recolector de basura se encarga de la limpieza.
Después de buscar una propiedad similar que podría usar para su MediaElement
, resulta que no hay una. Sin embargo, de acuerdo con una respuesta sobre el chacheoption para la publicación de medioselementos de MSDN, hay una manera (larga) de lograr esto ... a partir de la respuesta relevante:
No estoy seguro si su MediaElement está en un UserControl o no. pero sea cual sea el caso, puede configurar UserControl o Control en IsEnabled = false, que a su vez activará el controlador de eventos IsEnabledChanged. En él, coloque el código necesario para detener el MediaElement de la reproducción ME.Stop (), luego llame a ME.Clear () y ME.Source = null. Después de eso, no deberías encontrar problemas para eliminar el archivo fuente.
ME.Source = new Uri(MediaFilePath);
ME.Play();
...
private void DeleteButton_Click(object sender, RoutedEventArgs e)
{
ME.IsEnabled = false; // This will call the Event Handler IsEnabledChanged
System.IO.File.Delete(MediaFilePath);
// Now after the player was stopped and cleared and source set to null, it
// won''t object to deleting the file
}
private void ME_IsEnabledChanged(object sender, DependencyPropertyChangedEventArgs e)
{
ME.Stop();
ME.Clear();
ME.Source = null;
}
Espero que esto ayude.
Basado en @Sheridan, responda esto con lo que se me ocurrió que funciona.
Siempre que MediaElement
se detenga usando la función Stop()
, establezca Source
Property para null
esta manera:
ResetMediaElement()
{
mediaElement.Stop();
mediaElement.Source = null;
}
Esto cerrará la ruta adjunta al elemento multimedia, de modo que el recurso relacionado se pueda usar en otro lugar.
Si usa MediaElement, asegúrese de no ser mordido por este: http://msdn.microsoft.com/en-us/library/cc626563(v=vs.95).aspx
ArgumentNullException: MediaStreamSource es nulo.
...Después de llamar a este método, MediaElement.Source devuelve null. Si se llama y se establece MediaElement.Source, la última operación gana.
Si se elimina un MediaElement del árbol de la interfaz de usuario mientras tiene un MediaStreamSource abierto, las llamadas posteriores a SetSource pueden ignorarse. Para garantizar que las llamadas a featureSetSource funcionen, establezca la propiedad Source en null antes de separar MediaElement del árbol de la interfaz de usuario.
naturalmente uno esperaría, si solo usan SetSource (somestream) para usar SetSource (null) para liberar los recursos. No, pensaron "mejor", tienes que usar Source = null para liberar recursos y SetSource (null) arroja ArgumentNullException
eso es lo que yo llamo un error de diseño (rompe la regla de comportamiento "menos esperado" y causa errores que te pican solo en el tiempo de ejecución [a menos que alguien haya hecho una regla de análisis estático para detectar tal cosa - necesitaría metadatos por supuesto que algún argumento no puede ser nulo, como en los contratos de código])
Pude introducir este error mientras refactorizaba un código en el control AudioRecorder de ClipFlair Studio el otro día :-(
Tenga en cuenta que no puede usar en MediaElement algo como Source = stream para abrir un Stream, ya que es una propiedad Uri (no una propiedad Object para aceptar también Stream) y tiene que usar SetSource (stream) en su lugar, por lo que tendría también esperan poder usar SetSource (null) para liberar los recursos.
Actualización: Se corrigió esto en la clase AudioRecorderView (utiliza el patrón MVVM) de AudioRecorderControl, en el descriptor de acceso "set" de la propiedad Audio se necesitaba el siguiente patrón de null-guarding:
if (mediaStreamSource != null)
player.SetSource(mediaStreamSource);
//must set the source once, not every time we play the same audio,
//else with Mp3MediaSource it will throw DRM error
else
player.Source = null;
mediaElement.Stop();
mediaElement.ClearValue(MediaElement.SourceProperty);