Global MediaElement will not restart once stopped, wp7 - c#

I have an app that runs background music at the application level so that the music doesn't stop when the user navigates through pages. However, I also make use of a VideoBrush. As I found out, I cannot have the two running at the same time as the VideoBrush will crash when setting its source.
I found that if I set the source of the MediaElement to null when the user attempts to use the VideoBrush, that everything works. Sure the music stops, much to my chagrin, but no error happens.
However, when the user taps away from the VideoBrush, I am trying to make the music start back up (beginning is fine) to no avail. Simply put, I am having trouble getting the music to start up again.
Here is my code:
App.xaml
<Application.Resources>
<MediaElement x:Key="GlobalMedia" Source="minutelongsong.mp3"
MediaEnded="MediaElement_MediaEnded" Visibility="Collapsed" />
</Application.Resources>
App.xaml.cs
public static MediaElement GlobalMediaElement
{
get { return Current.Resources["GlobalMedia"] as MediaElement; }
}
private void Application_Launching(object sender, LaunchingEventArgs e)
{
var AppMediaElement = App.GlobalMediaElement;
AppMediaElement.Position = TimeSpan.Zero;
AppMediaElement.Play();
}
private void MediaElement_MediaEnded(object sender, RoutedEventArgs e)
{
var AppMediaElement = App.GlobalMediaElement;
AppMediaElement.Position = TimeSpan.Zero;
AppMediaElement.Play();
}
And now the page that is making use of the VideoBrush.
MainPage.xaml
<Canvas x:Name="viewfinderCanvas" Width="480" Height="800" HorizontalAlignment="Center" VerticalAlignment="Center" Visibility="Collapsed">
<Canvas.Background>
<VideoBrush x:Name="videoBrush" Stretch="Fill">
<VideoBrush.RelativeTransform>
<CompositeTransform x:Name="previewTransform"
CenterX=".5"
CenterY=".5" />
</VideoBrush.RelativeTransform>
</VideoBrush>
</Canvas.Background>
</Canvas>
MainPage.xaml.cs
private void Button_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
var AppMediaElement = App.GlobalMediaElement;
AppMediaElement.Pause();
AppMediaElement.Stop();
AppMediaElement.Source = null; //set it to null to allow the cam to be set.
if ((PhotoCamera.IsCameraTypeSupported(CameraType.Primary)))
{
viewfinderCanvas.Visibility = Visibility.Visible;
cam = new PhotoCamera(CameraType.Primary);
if (Orientation == PageOrientation.PortraitUp || Orientation == PageOrientation.PortraitDown || Orientation == PageOrientation.Portrait)
{
videoBrush.RelativeTransform = new CompositeTransform() { CenterX = 0.5, CenterY = 0.5, Rotation = 90 };
}
videoBrush.SetSource(cam);
}
When the user exits out of the camera VideoBrush by hitting an on screen button, this code is fired. It disposes the cam, and tries to get the music playing again if the user allows the music. However the music will not play, even with this code.
private void zoomout_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (cam != null)
{
cam.Dispose();
}
viewfinderCanvas.Visibility = Visibility.Collapsed;
if (allowingamemusic == true)
{
var AppMediaElement = App.Current.Resources["GlobalMedia"] as MediaElement;
AppMediaElement.Source = new Uri("minutelongsong.mp3", UriKind.RelativeOrAbsolute);
AppMediaElement.Position = TimeSpan.Zero;
AppMediaElement.Play(); //despite this here, it will not play. No error thrown.
}
}

I switch back and forth between capturing an image and audio in the same page on my phone app.
You were very close, but you also have to set the videoBrush source to something else or it won't let go of the resources.
So when you want to use the MediaElement, then first dispose of the camera like this:
cam.Dispose();
viewfinderBrush.SetSource(new MediaElement()); //so it will let go of cam
cam = null;
//now set source for MediaElemet and do whatever
And when you use the camera again:
mediaElement.Stop();
mediaElement.Source = null; //or else setting the source for the video brush will fail
//now set source for videoBrush and do whatever
Old question, but hopefully this will help someone... it took me a few tries to figure it out.

After writing this last night, and finally testing it this morning, I see what may have happened but am still having the problem of the music not replaying once it's stopped.
MediaElement.MediaFailed was for the entire time being called. I found out that it was calling: AG_E_NETWORK_ERROR. This error is thrown when Zune is running and my device is USB connected to the same computer.
It was suggested that I deploy my app to my phone, close zune, and disconnect the USB. I tried this, and the music still did not play once I tried to replay it. This also happened on the emulator too.
The same AG_E_NETWORK_ERROR is still being thrown.
Since then, I have given up on this as I spent a few hours not finding out how to make this happen. So, I have since gone with the MediaPlayer class and will be using that instead.
------ If anyone solves this problem, I will give you the checkmark for a correct answer.

Related

Video is not rendered in accord videoSourcePlayer control

I have an accord videoSourcePlayer control in my form.Why is it that it is not rendering the video that I select? Please see my code below:
// Open video file using DirectShow
private void openVideoFileusingDirectShowToolStripMenuItem_Click(object sender, EventArgs e)
{
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
// create video source
FileVideoSource = new FileVideoSource(openFileDialog.FileName);
// open it
sourceInitialiization = true;
OpenVideoSource(FileVideoSource);
}
}
// Open video source
private void OpenVideoSource(IVideoSource source)
{
// set busy cursor
this.Cursor = Cursors.WaitCursor;
// close previous video source
CloseVideoSource();
// start new video source
videoSourcePlayer.VideoSource = new AsyncVideoSource(source);
videoSourcePlayer.Start();
// reset statistics
statIndex = statReady = 0;
// start timers
timer.Start();
alarmTimer.Start();
//alarmTimer1.Start();
videoSource = source;
this.Cursor = Cursors.Default;
}
In my laptop where I initially coded this program, this works perfectly, but if I transfer it to another machine, say a desktop or another laptop, the code doesn't work anymore. It runs but it doesn't render the video and there is not error detected in the debugger too.
I tried downloading a sample video project from accord framework but I still couldn't get it to play a video on the desktop except on my laptop. What am I missing? Thank you.
Have you subscribed to the NewFrameReceived event?

MediaPlayer class listening for NaturalDuration.HasTimeSpan change

I am writing a custom audio player in c# using the MediaPlayer class. I have implemented a scroll bar so the user can seek through a track and this is where I am having the problem.
WHen the user selects an audio track (loaded from an xml playlist) the app calculates the length in seconds of the track and sets this as the max value for the scroll bar. This all works fine except the NaturalDuration.TimeSpan property sometimes returns 0 rather than the amount. I have proved this by adding a loop that exits when NaturalDuration.HasTimeSpan is true then returns the NaturalDuration.TimeSpan value.
My question is how can I just get the NaturalDuration.TimeSpan when the NaturalDuration.HasTimeSpan is changed to true?
The correct way to do this is to handle the MediaPlayer.MediaOpened event:
mediaPlayer = new MediaPlayer();
mediaPlayer.MediaOpened += MediaPlayer_MediaOpened;
mediaPlayer.Open(new Uri(mediaFilePath, UriKind.Absolute));
...
private void MediaPlayer_MediaOpened(object sender, EventArgs e)
{
if (mediaPlayer.NaturalDuration.HasTimeSpan)
{
SliderMaximum = mediaPlayer.NaturalDuration.TimeSpan.TotalSeconds;
mediaPlayer.Play();
}
}

PhotoCamera API: how to properly dispose it?

I'm using the PhotoCamera API to build a QR code scanning page (using ZXing). However, this page is only a small part of the app, and therefore it is not always shown. Thus, the application navigates between this page and some other pages with common controls.
The issue is that sometimes, after a scan, the whole application is slowed down to 30fps instead of 60fps with no real reason. I suspect that the camera is still running in the background, and the frame sync locks the app to 30fps, which is my issue: how to properly dispose of a page that uses the PhotoCamera API?
My XAML:
<Grid Background="Black">
<ProgressBar x:Name="PBar" IsIndeterminate="True" VerticalAlignment="Center" />
<Rectangle x:Name="ScanRect">
<Rectangle.Fill>
<VideoBrush x:Name="ScanVideoBrush" />
</Rectangle.Fill>
</Rectangle>
</Grid>
My C# to stop the scan process:
private void StopScan() {
if (analysisTimer != null) {
analysisTimer.Stop();
analysisTimer = null;
}
if (focusTimer != null) {
focusTimer.Stop();
focusTimer = null;
}
if (camera != null) {
camera.Dispose();
camera.Initialized -= OnCameraInitialized;
camera = null;
}
// Following two lines are a try to dispose stuff
// as much as possible, but the app still lags
// sometimes after a scan...
ScanVideoBrush.SetSource(new MediaElement());
ScanRect.Fill = new SolidColorBrush(Colors.Black);
}
Note: I'm testing the app on a Lumia 920.
Calling cam.Dispose(); should dispose the image source stream and free resources used by the Camera object, so that's fine.
Are you sure you are releasing memory, i.e unsubscribing from the PhotoCamera class Events?
When is your StopScan method called? A good practice could be to call it in OnNavigatingFrom of the PhoneApplicationPage.
Here is the code sample from MSDN that disposes the PhotoCamera:
protected override void OnNavigatingFrom(System.Windows.Navigation.NavigatingCancelEventArgs e)
{
if (cam != null)
{
// Dispose camera to minimize power consumption and to expedite shutdown.
cam.Dispose();
// Release memory, ensure garbage collection.
cam.Initialized -= cam_Initialized;
cam.CaptureCompleted -= cam_CaptureCompleted;
cam.CaptureImageAvailable -= cam_CaptureImageAvailable;
cam.CaptureThumbnailAvailable -= cam_CaptureThumbnailAvailable;
cam.AutoFocusCompleted -= cam_AutoFocusCompleted;
CameraButtons.ShutterKeyHalfPressed -= OnButtonHalfPress;
CameraButtons.ShutterKeyPressed -= OnButtonFullPress;
CameraButtons.ShutterKeyReleased -= OnButtonRelease;
}
}
Source

WinRT (re)play sound with mediaElement in c# .NET

I'm using the MediaElement class to play a simple sound on a button click. That works fine for me unless I'm making a double tap on it. On the second tap I want the old sound to stop playing and restart the sound. But the Stop Method doesn't work:
public static MediaElement SoundDelete;
public static void PlaySoundCash()
{
if (SessionHelper.getConfig("SoundDelete") == "true")
{
System.Diagnostics.Debug.WriteLine(SoundDelete.Position.ToString());
SoundDelete.Stop(); //dosn't work
SoundDelete.Position = new System.TimeSpan(0,0,0,0,0); //dosn't work
System.Diagnostics.Debug.WriteLine(SoundDelete.Position.ToString());
SoundDelete.Play();
}
}
In the console the timespan is never 0. How can I get the sound playing from the beginning?
I was having the exact same issue. It turns out adding the MediaElement to the Visual Tree will allow you to use this extra functionality.
Adding my MediaElements to the children of my base Grid solved these issues.
For example:
C#
public static MediaElement SoundDelete;
private void MediaInit()
{
// ...
// load your sound file into SoundDelete
// ...
BaseGrid.Children.Add(SoundDelete);
}
public static void PlaySoundCash()
{
System.Diagnostics.Debug.WriteLine(SoundDelete.Position.ToString());
SoundDelete.Stop();
SoundDelete.Position = new System.TimeSpan.Zero;
System.Diagnostics.Debug.WriteLine(SoundDelete.Position.ToString());
SoundDelete.Play();
}
or in XAML:
<Grid Name="BaseGrid">
<MediaElement Name="SoundDelete" Source="path_to_your_sound_file.mp3" />
</Grid>

Adding two music sources in WP7 app

In my WP7 gaming app , I want two music files to run. One is the background music and another follows the user action , say, user kills the enemy. I am using MediaElement to do this. I am facing two issues.
1) How to loop background music ?
2) As soon as second music starts, the first music stops and does not start back when the second music stops. I do not want background music to stop, they should overlap. How to do this ?
I am using silverlight.
XAML
<MediaElement x:Name="stroke" AutoPlay="False" />
<MediaElement x:Name="bmusic" AutoPlay="True" />
C#
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
base.OnNavigatedTo(e);
var settings = IsolatedStorageSettings.ApplicationSettings;
if (settings.Contains("bm"))
{
string hy=(string)settings["bm"];
//check if user has disabled music play
if (hy == "1")
{
bmplay = 1;
// play background music
bmusic.Source = new Uri("bmusic.mp3", UriKind.Relative);
bmusic.Play();
}
else
{
bmplay = 0;
}
}
else
{
bmplay = 1;
// play b music
bmusic.Source = new Uri("bmusic.mp3", UriKind.Relative);
bmusic.Play();
}
if (NavigationContext.QueryString.TryGetValue("msg", out msg))
{
// textBox1.Text +=" "+ msg;
find_move();
}
}
For repeating music you can use this:
Song s = Song.FromUri("song", new Uri(path));
FrameworkDispatcher.Update();
MediaPlayer.IsRepeating = repeat;
MediaPlayer.Play(s);
And try to use SoundEffect for sounds, they can be played simultaneously with background music.
Sound effect in windows phone 7

Categories

Resources