質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

Q&A

解決済

1回答

3840閲覧

WPFで複数の動画を順番に連続再生するには

pengin3

総合スコア1

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

1グッド

1クリップ

投稿2021/06/23 01:07

前提・実現したいこと

はじめまして。
最近プログラミングを勉強し始めた者です。

WPFのMediaElementを使って、選択した複数の動画ファイルを順番に再生するという
プログラムを開発中です。
動画ファイル001を再生し終わった後、MediaEndedで動画ファイル002を再生。
002が再生し終わると動画ファイル003を再生…というふうにしたいのですが、
MediaEndedでどういった処理を書けばよいのか分からなくなりました。
ご教授いただければ幸いです。

該当のソースコード

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Forms;//WpfでWindowsFormsのコントロールを使うために関連付けする using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace MediaPlayer_WpfApp { /// <summary> /// MainWindow.xaml の相互作用ロジック /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } string[] paths, files; private void Open_Button_Click(object sender, RoutedEventArgs e) //ボタンをクリックしたら以下の処理がされる //ListBoxを使ってファイルパスを読み込み、MediaElementで再生するには? { OpenFileDialog ofd = new OpenFileDialog(); //ファイル選択ダイアログが開く ofd.Multiselect = true; //複数選択をする if(ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK) //ダイアログボックスの表示=DialogResultの返り値(処理の結果)が「OK」なので、 //OKだとダイアログボックスが表示される? { files = ofd.SafeFileNames; //ダイアログボックスで選択された全てファイルのファイル名と拡張子の配列を取得。ファイルパスは含まれない paths = ofd.FileNames; //ダイアログボックスで選択された全てファイルのファイル名を取得 for (int x=0; x<files.Length; x++) //for(ループ文)(初期化式;条件式;反復式) //xは0; xはfiles.Lengthより小さい; xが1ずつ増えていく { TrackList.Items.Add(files[x]); //ListBoxにItem(要素。今回の場合はファイル)追加 //AddでItemコレクションに項目を追加する(ファイルがx個) } } } } }

補足情報(FW/ツールのバージョンなど)

開発環境はVisualStudio2019です。

TN8001👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

WPFはxamlとC#コードはセットですので、よほど長くない限り一緒に提示してください。

MediaEndedでどういった処理を書けばよいのか分からなくなりました。

Sourceに新しいファイルをセットします。
MediaElement.Source プロパティ (System.Windows.Controls) | Microsoft Docs

OpenFileDialogはWPFにもあるので、System.Windows.Formsを参照する必要はありません。
OpenFileDialog クラス (Microsoft.Win32) | Microsoft Docs


WPFのMediaElementはコントローラがないので、最低限の操作だけでも一苦労なんですよねぇ(UWPだと標準でオシャレなコントローラがついているのですが^^;

方法: MediaElement (再生、一時停止、停止、ボリューム、および速度) を制御する - WPF .NET Framework | Microsoft Docs
をベースにまともなシークバーにした参考実装です(シークバーは過去にいろいろ試しましたが、これが一番簡単で分かりやすいと思います)

xml

1<Window 2 x:Class="Questions345578.MainWindow" 3 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 4 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 5 Width="800" 6 Height="450"> 7 <Grid> 8 <Grid.ColumnDefinitions> 9 <ColumnDefinition /> 10 <ColumnDefinition Width="10" /> 11 <ColumnDefinition Width="4*" /> 12 </Grid.ColumnDefinitions> 13 <DockPanel> 14 <Button 15 Click="Open_Button_Click" 16 Content="Open" 17 DockPanel.Dock="Bottom" /> 18 <ListBox x:Name="TrackList" SelectionChanged="TrackList_SelectionChanged"> 19 <ListBox.ItemTemplate> 20 <DataTemplate> 21 <TextBlock Text="{Binding FileName}" ToolTip="{Binding FilePath}" /> 22 </DataTemplate> 23 </ListBox.ItemTemplate> 24 </ListBox> 25 </DockPanel> 26 <GridSplitter Grid.Column="1" HorizontalAlignment="Stretch" /> 27 <DockPanel Grid.Column="2" Background="Black"> 28 <StackPanel DockPanel.Dock="Bottom"> 29 <ProgressBar 30 x:Name="seekBar" 31 Height="20" 32 MouseDown="SeekBar_MouseDown" 33 MouseMove="SeekBar_MouseMove" 34 MouseUp="SeekBar_MouseUp" /> 35 <Grid> 36 <Grid.ColumnDefinitions> 37 <ColumnDefinition /> 38 <ColumnDefinition Width="Auto" /> 39 <ColumnDefinition /> 40 </Grid.ColumnDefinitions> 41 <Slider 42 Name="volumeSlider" 43 Width="100" 44 HorizontalAlignment="Right" 45 VerticalAlignment="Center" 46 Maximum="1" 47 ValueChanged="ChangeVolume" 48 Value="0.5" /> 49 <StackPanel 50 Grid.Column="1" 51 HorizontalAlignment="Center" 52 Orientation="Horizontal"> 53 <Button Click="OnPrevious" Content="" /> 54 <Button Click="OnPlay" Content="" /> 55 <Button Click="OnPause" Content="" /> 56 <Button Click="OnStop" Content="" /> 57 <Button Click="OnNext" Content="" /> 58 </StackPanel> 59 <TextBlock 60 x:Name="textBlock" 61 Grid.Column="2" 62 HorizontalAlignment="Right" 63 VerticalAlignment="Center" 64 Foreground="White" 65 Text="0:00:00 / 0:00:00" /> 66 </Grid> 67 </StackPanel> 68 <MediaElement 69 Name="mediaElement" 70 LoadedBehavior="Manual" 71 MediaEnded="OnMediaEnded" 72 MediaOpened="OnMediaOpened" 73 ScrubbingEnabled="True" 74 UnloadedBehavior="Stop" /> 75 </DockPanel> 76 </Grid> 77</Window>

cs

1using Microsoft.Win32; 2using System; 3using System.IO; 4using System.Windows; 5using System.Windows.Controls; 6using System.Windows.Input; 7using System.Windows.Threading; 8 9namespace Questions345578 10{ 11 class Item 12 { 13 public string FilePath { get; set; } 14 public string FileName => Path.GetFileName(FilePath); 15 } 16 17 public partial class MainWindow : Window 18 { 19 private readonly DispatcherTimer timer; // 再生位置監視タイマ 20 private bool isPlaying; // 再生中 21 private bool isDragging; // シークバードラッグ中 22 23 public MainWindow() 24 { 25 InitializeComponent(); 26 timer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(0.1), }; 27 timer.Tick += Timer_Tick; 28 } 29 30 31 private void Open_Button_Click(object sender, RoutedEventArgs e) 32 { 33 var ofd = new OpenFileDialog 34 { 35 Multiselect = true, 36 InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyVideos), 37 }; 38 39 bool? result = ofd.ShowDialog(); // ダイアログを開きます。閉じるまで進みません。 40 if (result == true) // OKの場合true。キャンセル・×の場合false。基本的にnullにはなりません。 41 { 42 foreach (var path in ofd.FileNames) 43 TrackList.Items.Add(new Item { FilePath = path, }); 44 } 45 } 46 47 private void TrackList_SelectionChanged(object sender, SelectionChangedEventArgs e) 48 { 49 if (TrackList.SelectedItem is Item item) 50 { 51 mediaElement.Source = new Uri(item.FilePath); 52 mediaElement.Play(); 53 isPlaying = true; 54 } 55 } 56 57 private void OnMediaOpened(object sender, EventArgs e) 58 { 59 seekBar.Maximum = mediaElement.NaturalDuration.TimeSpan.TotalMilliseconds; // 総再生ミリ秒 60 seekBar.Value = 0; 61 timer.Start(); 62 } 63 private void OnMediaEnded(object sender, EventArgs e) 64 { 65 mediaElement.Stop(); 66 timer.Stop(); 67 isPlaying = false; 68 OnNext(null, null); // 雑に呼び出しw 69 } 70 71 private void OnPrevious(object sender, RoutedEventArgs e) 72 { 73 mediaElement.Stop(); 74 timer.Stop(); 75 if (0 < TrackList.SelectedIndex) // 前を選択できれば。。選択 76 TrackList.SelectedIndex--; 77 } 78 private void OnNext(object sender, RoutedEventArgs e) 79 { 80 mediaElement.Stop(); 81 timer.Stop(); 82 if (TrackList.SelectedIndex < TrackList.Items.Count - 1) // 後を選択できれば。。選択 83 TrackList.SelectedIndex++; 84 } 85 86 private void Timer_Tick(object sender, EventArgs e) 87 { 88 seekBar.Value = mediaElement.Position.TotalMilliseconds; 89 var position = mediaElement.Position; // 再生現在位置 90 var total = mediaElement.NaturalDuration.TimeSpan; // 総再生時間 91 textBlock.Text = $"{position:h\:mm\:ss} / {total:h\:mm\:ss}"; 92 } 93 94 private void SeekBar_MouseDown(object sender, MouseButtonEventArgs e) 95 { 96 isDragging = true; 97 seekBar.CaptureMouse(); // MouseUpを確実にとるためキャプチャ 98 99 // 総再生ミリ秒 * シーク位置の割合(例えば真ん中だったら0.5) 100 seekBar.Value = seekBar.Maximum * (e.GetPosition(seekBar).X / seekBar.ActualWidth); 101 mediaElement.Position = TimeSpan.FromMilliseconds(seekBar.Value); // seekBar.Valueはミリ秒単位なので 102 103 mediaElement.Pause(); // PlayしながらシークするとガチャつくのでPause 104 } 105 private void SeekBar_MouseMove(object sender, MouseEventArgs e) 106 { 107 if (isDragging) 108 { 109 seekBar.Value = seekBar.Maximum * (e.GetPosition(seekBar).X / seekBar.ActualWidth); 110 mediaElement.Position = TimeSpan.FromMilliseconds(seekBar.Value); 111 } 112 } 113 private void SeekBar_MouseUp(object sender, MouseButtonEventArgs e) 114 { 115 isDragging = false; 116 seekBar.ReleaseMouseCapture(); 117 mediaElement.Position = TimeSpan.FromMilliseconds(seekBar.Value); 118 if (isPlaying) mediaElement.Play(); // Play状態復元 119 } 120 121 private void OnPlay(object sender, RoutedEventArgs args) 122 { 123 mediaElement.Play(); 124 timer.Start(); 125 isPlaying = true; 126 127 } 128 private void OnPause(object sender, RoutedEventArgs e) 129 { 130 mediaElement.Pause(); 131 timer.Stop(); 132 isPlaying = false; 133 } 134 private void OnStop(object sender, RoutedEventArgs e) 135 { 136 mediaElement.Stop(); 137 timer.Stop(); 138 isPlaying = false; 139 } 140 141 private void ChangeVolume(object sender, RoutedPropertyChangedEventArgs<double> args) 142 { 143 if (mediaElement != null) 144 mediaElement.Volume = volumeSlider.Value; 145 } 146 } 147}

アプリ画像

投稿2021/06/23 13:57

編集2023/07/27 16:01
TN8001

総合スコア9862

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

pengin3

2021/06/24 00:26

ありがとうございます! 実現したいと思ったことがすべて実現できました。 関数のことも、どうしてこのコードが出てくるんだろうとか、まだ全然分かっていないので、 ひとつひとつ調べていってどう動いているのか学習していきます。 本当にありがとうございます。 WPFはxamlとC#コードの点もご指摘ありがとうございます。 確かにセットなんだったら一緒に提示すべきでした。
TN8001

2021/06/24 10:08

回答コードの不明点はお気軽にコメントください。 一通り確認し質問が解決されたと思ったら解決済みにしてください。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問