開発環境 Microsoft Visual Studio Express 2013 for Windows Desktop
実行環境 Microsoft Windows 8.1 (64bit)
プロジェクトの種類 Visual C#/WPF アプリケーション
プロジェクト名 WpfMediaPlayer2

MainWindow.xaml
<Window x:Class="WpfMediaPlayer2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525"
        AllowDrop="True" Drop="Window_Drop"
        KeyDown="Window_KeyDown">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="10"/>
            <RowDefinition Height="25"/>
        </Grid.RowDefinitions>
        <Border Background="Black"/>
        <MediaElement Name="media" LoadedBehavior="Manual" UnloadedBehavior="Manual"
                      MediaOpened="media_MediaOpened"/>
        <ProgressBar Name="progress" MouseUp="progress_MouseUp" Grid.Row="1"/>
        <Label Name="label" Grid.Row="2"/>
    </Grid>
</Window>
 

MainWindow.xaml.cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Windows;
using System.Windows.Input;
using System.Windows.Threading;
 
namespace WpfMediaPlayer2
{
    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window
    {
        enum Status { Stop, Play, Pause }
 
        private Status _status = Status.Stop;
        private DispatcherTimer _timer;
        private string _duration = "";
        private List<TimeSpan> _playlist;
        private int _plindex;
 
        public MainWindow()
        {
            InitializeComponent();
 
            _timer = new DispatcherTimer();
            _timer.Interval = TimeSpan.FromSeconds(1);
            _timer.Tick += _timer_Tick;
            _timer.Start();
        }
 
        void _timer_Tick(object sender, EventArgs e)
        {
            TimeSpan ts = media.Position;
            label.Content = String.Format("{0} {1} / {2}",
                _status, ts.ToString(@"hh\:mm\:ss"), _duration);
 
            progress.Value = ts.TotalMilliseconds;
 
            if (_status == Status.Play)
            {
                if (0 < _playlist.Count)
                {
                    if (_playlist[_plindex] <= ts)
                    {
                        if (_playlist.Count <= ++_plindex)
                        {
                            _plindex = 0;
                        }
                        media.Position = _playlist[_plindex++];
                    }
                }
            }
        }
 
        private void Window_Drop(object sender, DragEventArgs e)
        {
            string[] files = e.Data.GetData(DataFormats.FileDrop) as string[];
            string path = files[0];
            string ext = Path.GetExtension(path);
            string dir = Path.GetDirectoryName(path);
 
            _playlist = new List<TimeSpan>();
            _plindex = 0;
            if (ext == ".txt")
            {
                string file;
                using (var sr = new StreamReader(path))
                {
                    file = sr.ReadLine();
                    string line;
                    while ((line = sr.ReadLine()) != null)
                    {
                        string[] fields = line.Split();
                        foreach (var s in fields)
                        {
                            var ts = TimeSpan.Parse(s);
                            _playlist.Add(ts);
                        }
                    }
                }
                path = String.Format(@"{0}\{1}", dir, file);
            }
 
            media.Source = new Uri(path);
            if (0 < _playlist.Count)
            {
                media.Position = _playlist[_plindex++];
            }
            media.Play();
            _status = Status.Play;
        }
 
        private void Window_KeyDown(object sender, KeyEventArgs e)
        {
            switch (e.Key)
            {
                case Key.Escape:
                    media.Stop();
                    _status = Status.Stop;
                    break;
 
                case Key.Space:
                    if (_status == Status.Play)
                    {
                        media.Pause();
                        _status = Status.Pause;
                    }
                    else
                    {
                        media.Play();
                        _status = Status.Play;
                    }
                    break;
 
                case Key.Left:
                    media.Position -= new TimeSpan(0, 0, getSeconds());
                    break;
 
                case Key.Right:
                    media.Position += new TimeSpan(0, 0, getSeconds());
                    break;
            }
        }
 
        private int getSeconds()
        {
            ModifierKeys mod = Keyboard.Modifiers;
            if ((mod & ModifierKeys.Control) != ModifierKeys.None) return 60;
            if ((mod & ModifierKeys.Shift) != ModifierKeys.None) return 300;
            return 10;
        }
 
        private void media_MediaOpened(object sender, RoutedEventArgs e)
        {
            Duration dur = media.NaturalDuration;
            _duration = dur.ToString();
            progress.Maximum = dur.TimeSpan.TotalMilliseconds;
        }
 
        private void progress_MouseUp(object sender, MouseButtonEventArgs e)
        {
            Point pt = e.GetPosition(progress);
            progress.Value = progress.Maximum * pt.X / progress.ActualWidth;
            media.Position = new TimeSpan(0, 0, 0, 0, (int)progress.Value);
        }
    }
}
 

sample.txt
sample.mp4
00:01:30.500 00:01:40.000
00:02:00.000 00:02:10.000
 
最終更新:2014年07月28日 11:43