MediaElement źle pokazuje NaturalDuration

MediaElement źle pokazuje NaturalDuration
gswidwa
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 839
0

Spotkaliście się, że MediaElement.Position jest większe od MediaElement.NaturalDuration.TimeSpan? Nigdzie w internecie nie widzę nic na ten temat

MS
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 328
0

Z tego co tutaj podają:
https://msdn.microsoft.com/pl-pl/library/system.windows.controls.mediaelement.position(v=vs.110).aspx

Setting this property can enable you to jump to different points in playback (also known as seeking). Not all media types allow seek operations. The MediaFailed event will fire if the media source does not allow seeking. [...] This property can be set only when the Clock property is null. When the Clock property is non-null, the timing engine controls media playback behavior.

Chyba nie ma przeciwwskazań, by ustawić ręcznie Position, które będzie większe od NaturalDuration. Czym jest Twój Clock? Opisz może coś więcej, co próbujesz w ogóle odtworzyć?

gswidwa
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 839
0

Chodzi o to, że mam timer i co kilka sekund sprawdzam NaturalDuration i Position. Używa tego inna kontrolka działająca jak Slider
screenshot-20170813034037.png

Niestety jak widać w tym utworze będę miał nieprawidłowe wyniki w
screenshot-20170813034143.png

Postęp odtwarzania utworu wychodzi poza skalę :(

MS
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 328
0

mam timer i co kilka sekund sprawdzam NaturalDuration i Position

Bez kodu ciężko coś więcej powiedzieć, ale jak rozumiem zrobiłeś coś w stylu:
https://stackoverflow.com/a/27688947
Masz ustawione Maximum tego slidera w zdarzeniu MediaOpened? Zobacz tutaj przykład:
https://docs.microsoft.com/en-us/dotnet/framework/wpf/graphics-multimedia/how-to-control-a-mediaelement-play-pause-stop-volume-and-speed

gswidwa
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 839
0

Ale ja właśnie tak robię:

Kopiuj
private void hMediaElement_MediaOpened(object sender, RoutedEventArgs e)
        {
            Model.SetPlayingStatus(ePlayingStatus.Play);
            Model.SetLastTrackMessage(eTrackMessage.TrackPlay);

            MediaElement me = hMediaElement;
            Model.SetTotalTimeInfo(GetTrackDuration());
            
            _LogChanged("Track is Playing", eDirection.Sender);

            _PlayingStatusChanged(ePlayingStatus.Play, TrackInfo);
            _TrackMessageChanged(eTrackMessage.TrackPlay, null);
        }
Kopiuj
private TimeSpan GetTrackDuration()
        {
            MediaElement me = hMediaElement;
           return (me.NaturalDuration.HasTimeSpan) ? me.NaturalDuration.TimeSpan : TimeSpan.Zero;
        }

Pozycję ustalam:

Kopiuj
private void MediaTimerTick()
        {
            _PlayingProgressChanged(hMediaElement.Position, GetTrackDuration());
        }

public event EventHandler<PlayingProgressEventArgs> PlayingProgressChanged;
        private void _PlayingProgressChanged(TimeSpan Position, TimeSpan Duration)
        {
            PlayingProgressChanged?.Invoke(this, new PlayingProgressEventArgs(Position, Duration));
        }

Problem w tym, że dla większości piosenek działa mi dobrze, tylko dla niektórych mp3 całkowita długość utworu jest za mała o np. pół sekundy.

gswidwa
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 839
0

Tutaj jedna z piosenek, która źle mi wyświetla NaturalDuration

MS
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 328
0

@gswidwa: sprawdziłem u siebie utwór i u mnie działa ;) Kod na bardzo szybko:

Kopiuj
public MainWindow()
{
	InitializeComponent();

	var timer = new DispatcherTimer {Interval = TimeSpan.FromMilliseconds(250)};
	timer.Tick += this.TimerOnTick;
	timer.Start();
}

private void TimerOnTick(object sender, EventArgs eventArgs)
{
	var pos = this.MediaElement0.Position;
	this.Slider0.Value = pos.TotalMilliseconds;
	this.TxtPos.Text = pos.ToString();
}

private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
	this.MediaElement0.Source = new Uri(/*ścieżka do utworu*/);
}

private void MediaElement0_OnMediaOpened(object sender, RoutedEventArgs e)
{
	this.Slider0.Maximum = this.MediaElement0.NaturalDuration.TimeSpan.TotalMilliseconds;
	this.TxtDur.Text = this.MediaElement0.NaturalDuration.ToString();
}

private void Slider0_OnValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
	var sliderValue = (int)this.Slider0.Value;
	var ts = new TimeSpan(0, 0, 0, 0, sliderValue);
	this.MediaElement0.Position = ts;
}
Kopiuj
<DockPanel LastChildFill="True">
	<TextBlock DockPanel.Dock="Top" Name="TxtPos"></TextBlock>
	<TextBlock DockPanel.Dock="Top" Name="TxtDur"></TextBlock>
	<Button DockPanel.Dock="Bottom" Click="ButtonBase_OnClick">Test</Button>
	<Slider DockPanel.Dock="Bottom" Name="Slider0" ValueChanged="Slider0_OnValueChanged"></Slider>
	<MediaElement Name="MediaElement0" DockPanel.Dock="Top" MediaOpened="MediaElement0_OnMediaOpened"></MediaElement>
</DockPanel>

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.