Источник mediatimeline не загружается должным образом при использовании относительного пути - WPF

Я пытаюсь воспроизвести фоновую музыку в приложении WPF, но музыка не воспроизводится, когда я использую относительный путь.

Это не работает:

<Storyboard x:Key="PlaySoundStoryboard">
            <MediaTimeline Storyboard.TargetName="myMediaElement"  Source="pack://application:,,,/Music/music.mp3" />
</Storyboard>

Однако, когда я выбираю полный путь в качестве источника, он работает: (Музыка также воспроизводится, когда я не запускаю приложение, а просто открываю код в Visual Studio, поэтому, если у кого-то есть исправление для этого, пожалуйста, дайте мне знать)

<Storyboard x:Key="PlaySoundStoryboard">
            <MediaTimeline Storyboard.TargetName="myMediaElement"  Source="D:\Documenten\Application\View\Music\music.mp3" />
</Storyboard>

Я также попытался просто указать папку, как предлагается здесь: Set Mediaelement Source на относительный URI в коде WPF

<Storyboard x:Key="PlaySoundStoryboard">
        <MediaTimeline Storyboard.TargetName="myMediaElement"  Source="Music/music.mp3" />

The relative path does work when I use it for images so I am a little bit confused, this works:

 <Button.Content>
            <Image Source="pack://application:,,,/Img/music-and-multimedia.png"/>
 </Button.Content>

Изменить: вот мой медиа-элемент

    <MediaElement x:Name="myMediaElement"  />
    <Button Name="playbutton" Grid.Column="0" Width="40" Height="40" Background="Transparent" BorderThickness="0" HorizontalAlignment="Left">
        <Button.Content>
            <Image Source="pack://application:,,,/Img/music-and-multimedia.png"/>
        </Button.Content>

    </Button>
    <Button Name="stopbutton" Grid.Column="1" Width="40" Height="40" Background="Transparent" BorderThickness="0" HorizontalAlignment="Left">
        <Button.Content>
            <Image Source="pack://application:,,,/Img/mute.png"/>
        </Button.Content>
    </Button>

А вот мои Grid.Triggers:

     <Grid.Triggers>
        <EventTrigger RoutedEvent="FrameworkElement.Loaded">
            <BeginStoryboard Storyboard="{StaticResource PlaySoundStoryboard}"  Name="theStoryboard"  />
        </EventTrigger>
        <EventTrigger RoutedEvent="ButtonBase.Click" SourceName="playbutton">
            <ResumeStoryboard BeginStoryboardName="theStoryboard" />
        </EventTrigger>
        <EventTrigger RoutedEvent="ButtonBase.Click" SourceName="stopbutton">
            <PauseStoryboard BeginStoryboardName="theStoryboard" />
        </EventTrigger>
    </Grid.Triggers>

wpf
person RandomStacker    schedule 09.05.2020    source источник
comment
Вы установили для свойства Copy to Output Directory mp3-файла значение Copy Always? В противном случае файл не копируется в каталог bin, и относительный путь не указывает ни на что во время выполнения.   -  person Corentin Pane    schedule 09.05.2020
comment
Для MP3-файла установлено значение «Всегда копировать».   -  person RandomStacker    schedule 09.05.2020
comment
Пожалуйста, включите полный пример XAML, показывающий ваш MediaElement, потому что я не могу воспроизвести вашу проблему.   -  person Corentin Pane    schedule 09.05.2020
comment
Я внес правку в исходный пост.   -  person RandomStacker    schedule 09.05.2020
comment
Этот фрагмент кода работает для меня, так что у вас, вероятно, проблема с ресурсами? Убедитесь, что вы создали ресурсы, прежде чем ссылаться на них. ` ‹Grid› ‹MediaElement Name=myMediaElement/› ‹Grid.Triggers› ‹EventTrigger RoutedEvent=Loaded› ‹BeginStoryboard› ‹Storyboard› ‹MediaTimeline Storyboard.TargetName=myMediaElement Source=/Music/music.mp3 /› ‹/Storyboard› ‹ /BeginStoryboard› ‹/EventTrigger› ‹/Grid.Triggers› ‹/Grid›`   -  person Corentin Pane    schedule 09.05.2020


Ответы (1)


Эту проблему можно решить, извлекая аудио/медиаконтент из ресурсов и записывая его во временный файл. Затем установите URI для источника MediaTimeline, чтобы сделать ссылку на временный файл.

var resourceName = "YourAssemblyName.Music.music.mp3"; // Embedded resource 
using (var fstream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName))
{
    var ext = resourceName.Substring(resourceName.LastIndexOf("."));
    var pathfile = System.IO.Path.GetTempPath() + Guid.NewGuid().ToString() + ext;
    using (FileStream outputFileStream = new FileStream(pathfile, FileMode.Create))
    {
        fstream.CopyTo(outputFileStream);
    }
    // "mt" is name of the MediaTimeline element 
    mt.Source = new Uri(pathfile, UriKind.RelativeOrAbsolute);
}

Удалите временно созданный файл pathfile, когда он больше не нужен.

person Jackdaw    schedule 31.10.2020