WindowsAppSDK
WindowsAppSDK copied to clipboard
Windows.Media.Playback.MediaPlayer Seeking jumps forward 9 seconds on certain files.
Describe the bug
I have a slider bound to an object that updates it as the position of a MediaPlayer changes, and allows it to update the position by dragging along the slider. This works for most songs, but sone of the songs I have will jump forward about 9 seconds from where I click on the slider, or where I set the position programatically. This also only happens once playing. For example, if I pause the playback, then set the time it seems to set properly, but when I start playback again it jumps forward 9 seconds. This is using
- Microsoft.UI.XAML 2.8.6
- Microsoft.Windows.SDK.BuildTools 10.0.26100.1
- Microsoft.WindowsAppSDK 1.5.240627000
The app is being tested unpackaged.
Steps to reproduce the bug
Demo Code adapted from the larger project where I'm experiencing this issue. Note that this code works fine with most files I've tried. If asked I can provide a few of the files that cause the issue for me (one example is the flac file for Hollowheart - Porter Robinson): MainWindow.cs
public sealed partial class MainWindow : Window
{
public MainWindow()
{
this.InitializeComponent();
InitMediaPlayer();
}
public async static void InitMediaPlayer()
{
// Setup MediaPlayer/MediaPlaybackList
StateManager.NowPlayingMediaPlayer = new MediaPlayer();
StateManager.NowPlayingMediaPlayer.Volume = 0.02;
StateManager.PlaybackList = new MediaPlaybackList();
StateManager.PlaybackList.MaxPlayedItemsToKeepOpen = 5;
StateManager.PlaybackList.AutoRepeatEnabled = false;
StateManager.NowPlayingMediaPlayer.Source = StateManager.PlaybackList;
StateManager.NowPlayingMediaPlayer.AutoPlay = true;
// Get track
var trackStream = File.OpenRead($"<Music File Path Here>");
var memoryStream = new MemoryStream();
await trackStream.CopyToAsync(memoryStream);
memoryStream.Seek(0, SeekOrigin.Begin);
var mSource = MediaSource.CreateFromStream(memoryStream.AsRandomAccessStream(), "flac");
var playbackItem = new MediaPlaybackItem(mSource);
if (playbackItem == null)
{
return;
}
// Set track
StateManager.PlaybackList.Items.Clear();
StateManager.PlaybackList.Items.Add(playbackItem);
StateManager.NowPlayingMediaPlayer.Play();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
InitMediaPlayer();
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
StateManager.NowPlayingMediaPlayer.Position = TimeSpan.FromSeconds(20);
}
}
MainWindow.xaml
<Window
x:Class="mediaplayer.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:mediaplayer"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid>
<Grid.Resources>
<local:DoubleDurationToTime x:Key="DoubleDurationToTime"/>
</Grid.Resources>
<Button Click="Button_Click"
HorizontalAlignment="Center"
Margin="0,0,0,400">Restart</Button>
<Button Click="Button_Click_1"
HorizontalAlignment="Center"
Margin="0,0,0,700">Set 20 Seconds</Button>
<TextBlock Grid.Column="3"
Text="{x:Bind local:StateManager.PlaybackInfo.PositionStr, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Grid.Row="1"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Margin="10,18,0,0"/>
<TextBlock Grid.Column="3"
Text="{x:Bind local:StateManager.PlaybackInfo.DurationStr, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Grid.Row="1"
VerticalAlignment="Top"
HorizontalAlignment="Right"
Margin="0,18,20,0"/>
<Slider x:Name="TrackProgress"
Height="30"
ThumbToolTipValueConverter="{StaticResource DoubleDurationToTime}"
Value="{x:Bind local:StateManager.PlaybackInfo.Position, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Maximum="{x:Bind local:StateManager.PlaybackInfo.Duration, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Grid.Column="3"
Grid.Row="1"
Margin="9,0,20,10"/>
</Grid>
</Window>
PlaybackObservables.cs
public class PlaybackObserables : INotifyPropertyChanged
{
private double _position;
private double _duration;
private readonly DispatcherTimer timer;
public double Position
{
get => _position;
set
{
if (_position != value)
{
_position = value;
StateManager.NowPlayingMediaPlayer.PlaybackSession.Position = TimeSpan.FromMilliseconds(value);
OnPropertyChanged();
OnPropertyChanged("PositionStr");
}
}
}
public string PositionStr
{
get
{
try
{
var str = TimeSpan.FromMilliseconds(_position).ToString(@"hh\:mm\:ss");
return str;
}
catch (Exception)
{
return "Ukwn";
}
}
set
{
}
}
public string DurationStr
{
get
{
try
{
var str = TimeSpan.FromMilliseconds(_duration).ToString(@"hh\:mm\:ss");
return str;
}
catch (Exception)
{
return "Ukwn";
}
}
set
{
}
}
public double Duration
{
get => _duration;
set
{
if (_duration != value)
{
_duration = value;
OnPropertyChanged();
OnPropertyChanged("DurationStr");
}
}
}
public PlaybackObserables()
{
Position = 0;
Duration = 100;
timer = new DispatcherTimer
{
Interval = TimeSpan.FromMilliseconds(100)
};
timer.Tick += Timer_Tick;
timer.Start();
}
private void Timer_Tick(object sender, object e)
{
try
{
if (_position != StateManager.NowPlayingMediaPlayer.PlaybackSession.Position.TotalMilliseconds)
{
Debug.WriteLine($"{StateManager.NowPlayingMediaPlayer.PlaybackSession.Position.TotalMilliseconds}");
_position = StateManager.NowPlayingMediaPlayer.PlaybackSession.Position.TotalMilliseconds;
//PlaybackManager.NowPlayingMediaPlayer.PlaybackSession.Position = TimeSpan.FromSeconds(10);
OnPropertyChanged("Position");
OnPropertyChanged("PositionStr");
}
if (_duration != StateManager.NowPlayingMediaPlayer.PlaybackSession.NaturalDuration.TotalMilliseconds)
{
_duration = StateManager.NowPlayingMediaPlayer.PlaybackSession.NaturalDuration.TotalMilliseconds;
OnPropertyChanged("Duration");
OnPropertyChanged("DurationStr");
}
}
catch (Exception)
{
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
StateManager.cs
internal class StateManager
{
public static PlaybackObserables PlaybackInfo = new PlaybackObserables() { Duration = 100, Position = 0 };
public static MediaPlayer NowPlayingMediaPlayer { get; set; }
public static MediaStreamSource StreamSource;
public static MediaPlaybackList PlaybackList;
}
DoubleDurationToTime.cs
public class DoubleDurationToTime : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
double duration = (double)value;
if (duration == null)
{
return "00:00:00";
}
try
{
var str = TimeSpan.FromMilliseconds(duration).ToString(@"hh\:mm\:ss");
return str;
}
catch (Exception)
{
return "Ukwn";
}
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}
}
Expected behavior
Song should not jump forward 9 seconds after being set to a set time. The expected behavior does happen, just inconsistently between files.
Screenshots
NuGet package version
Windows App SDK 1.5.5: 1.5.240627000
Packaging type
Unpackaged
Windows version
Insider Build (xxxxx)
IDE
Visual Studio 2022
Additional context
No response