First post so be gentle and sorry for a long post but wanted to provide as much detail as I could.
I have a MediaElement control inside a usercontrol with the LoadedBehaviour property set to manual, see below. When I click on the 'Open' button the handler code includes playing the media so that I can ready the duration properrty in the MediaOpened event handler, which it does successfully. The MediaOpened handler stops the playing when I'm just requiring the media length.
I also want to load a playlist at the start of the program and fill a datagrid with information, one element being the length of the media.
XAML
<MediaElement Grid.Row="5" Name="MediaEL" Grid.ColumnSpan="6" MediaOpened="MediaEL_MediaOpened" LoadedBehavior="Manual" Height="169" />
<DataGrid Grid.Row="1" Grid.ColumnSpan="6" Name="dgPlayList" AutoGenerateColumns="False" Height="300" >
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Position}" Header="#" Width="30"/>
<DataGridTextColumn Binding="{Binding Title}" Header="Title" Width="182"/>
<DataGridTextColumn Binding="{Binding Time}" Header="Time" Width="50"/>
<DataGridCheckBoxColumn Binding="{Binding Dnp}" Header="Dnp" Width="35"/>
<DataGridTextColumn Binding="{Binding Location}" Visibility="Hidden" />
</DataGrid.Columns>
</DataGrid>
C#
private void btnOpen_Click(object sender, RoutedEventArgs e)
{
System.Windows.Forms.OpenFileDialog ofd = new System.Windows.Forms.OpenFileDialog();
if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
MediaEL.Source = new Uri(ofd.FileName);
btnPlay.IsEnabled = true;
MediaEL.Visibility = Visibility.Hidden;
SettingTime = true;
MediaEL.Play();
}
}
private void MediaEL_MediaOpened(object sender, RoutedEventArgs e)
{
if (MediaEL.NaturalDuration.HasTimeSpan)
{
TimeSpan ts = MediaEL.NaturalDuration.TimeSpan;
Length.Content = FormatLength(ts.TotalSeconds); // make it look like 00:00:00
seekBar.Maximum = ts.TotalSeconds;
seekBar.SmallChange = 1;
seekBar.LargeChange = Math.Min(10, ts.Seconds / 10);
}
if (!SettingTime)
timer.Start();
else
{
SettingTime = false;
MediaEL.Stop();
MediaEL.Visibility = Visibility.Visible;
MediaEL.Close();
}
}
dgPlayList.ItemsSource = LoadPlayListData();
is called in the window loaded method.
I have commented out in the method below the foreach statement until I get one working.
Now the PROBLEM is when trying to get the media length to fill the datagrid time column the MediaOpened event does NOT fire and I cannot see why not and have exhausted searches on the subject.
Any thoughts would be most appreciated !
Thanks, Jim
C#
private ObservableCollection<PlayListEntry> LoadPlayListData()
{
var playListEntries = new ObservableCollection<PlayListEntry>();
var position = 1;
var bPlay = false;
var doc = new XmlDocument();
doc.Load(System.IO.Path.GetDirectoryName(Assembly.GetExecutingAssembly().GetName().CodeBase) + @"/mpcplaylist.xml");
var root = doc.DocumentElement;
var nodes = root.SelectNodes("/playlist/media");
XmlNode node = nodes[0];
if (node.InnerXml.Contains("title"))
{
var xmlElement = node["title"];
if (xmlElement != null)
Title = xmlElement.InnerText;
}
if (node.InnerXml.Contains("artist"))
{
var xmlElement = node["artist"];
if (xmlElement != null)
Artist = xmlElement.InnerText;
}
if (node.InnerXml.Contains("location"))
{
var xmlElement = node["location"];
if (xmlElement != null)
Location = xmlElement.InnerText;
}
if (node.InnerXml.Contains("include"))
{
var xmlElement = node["include"];
if (xmlElement != null)
Include = xmlElement.InnerText;
}
if (Include == "No")
bPlay = true;
else
bPlay = false;
//foreach (XmlNode node in nodes)
//{
// if (node.InnerXml.Contains("title"))
// {
// var xmlElement = node["title"];
// if (xmlElement != null)
// Title = xmlElement.InnerText;
// }
// if (node.InnerXml.Contains("artist"))
// {
// var xmlElement = node["artist"];
// if (xmlElement != null)
// Artist = xmlElement.InnerText;
// }
// if (node.InnerXml.Contains("location"))
// {
// var xmlElement = node["location"];
// if (xmlElement != null)
// Location = xmlElement.InnerText;
// }
// if (node.InnerXml.Contains("include"))
// {
// var xmlElement = node["include"];
// if (xmlElement != null)
// Include = xmlElement.InnerText;
// }
// if (Include == "No")
// bPlay = true;
// else
// bPlay = false;
MediaEL.Source = new Uri(Location);
SettingTime = true;
MediaEL.Play();
Medialength = Length.Content.ToString();
playListEntries.Add(new PlayListEntry()
{
Dnp = bPlay,
Position = position++,
Time = Medialength,
Title = Title,
Location = Location
});
//}
return playListEntries;
}
Solution was...
I grab the first entry from the xml playlist and set the source property then call the play method to get the duration. Now in the Media Opened event I then grab the next entry and do the same until I have the duration for all of the media items in the list.
That was the key have the media opened event get the next entry after the first had been handled.
That said I have another issue with threading and the control but I will create a new post for that.
Thanks, Jim
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With