WPF写的音乐播放器

使用C# WPF写的哦,写看成果:

3.JPG 

 


第一步:首先把要实现的功能写出来,就用PS简单画了个界面

 

第二步:分析一下每个功能是怎样实现的:

项目二: 音乐播放器
基本功能: 歌曲列表、上一曲、下一曲、暂停、重播
扩展功能:自动下一曲、歌词显示、播放进度选择

支持的音频格式:
WAV;MP3

功能:打开音乐
        1.加入播放列表
        2.找同目录下歌词
        3.开始播放
        
功能:暂停、播放
        1.无文件时,打开文件
        2.播放时,修改为(暂停)、开始timer
        3.暂停时,修改为(播放)、停止timer

功能:重播
        1.调用方法

功能:上一曲、下一曲
        1.调用方法

功能:自动下一曲
        1.添加一个事件,播放完成后调用
        2.判断checkbox是否勾选
        3.判断当前文件在列表中的位置
        4.有下一曲? 播放下一曲
        5.否则,什么也不做

功能:显示歌词
        1.是否有歌词文件.是否有歌手图片
        2.正则匹配,把能读取的读进来
        3.Timer,检查播放进度
        4.显示歌词,显示歌手写真
        正则:
        (?<=^\[)(\d+:\d+\.\d+).(.+)(?=$)
        (?<=^)(\[\d+:\d+\.\d+).(.+)(?=$)

[*]功能:音量调节
        1.API。。。...OK
        
控件:进度条
        1.拖动 --> 改变进度...OK
        2.事件 --> 更新进度...OK
        3.没有文件时锁定.

控件:播放列表
        1.双击 --> 播放...OK
        2.右键 --> 添加...OK
        3.右键 --> 删除...OK


好了,实现代码如下:

界面代码:

 

<Window x:Class="Player.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="风车播放器 bete1" Height="650" Width="825" WindowStartupLocation="CenterScreen" ResizeMode="NoResize">
    <Grid>
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition MinWidth="100"  Width="315"></ColumnDefinition>
                <ColumnDefinition></ColumnDefinition>
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="120"></RowDefinition>
                <RowDefinition></RowDefinition>
            </Grid.RowDefinitions>
            <MediaElement Name="mediaelement"  Visibility="Hidden" LoadedBehavior="Manual" />
            <!--写控件-->
            <Canvas>
                <TextBlock Canvas.Left="32" Canvas.Top="13" Height="23" Name="txt_title" Text="Follow your heart~Listening~~" Width="233" TextAlignment="Center" />
                <Slider Canvas.Left="9" Canvas.Top="43" Name="sd_pos" Width="266" Maximum="100" SmallChange="1"  PreviewMouseLeftButtonDown="sd_pos_ui_MouseDown" PreviewMouseLeftButtonUp="sd_pos_ui_MouseUp" IsMoveToPointEnabled="False" />
                <Slider Canvas.Left="281" Canvas.Top="6" Height="70" Name="sd_vol"  Orientation="Vertical" Value="5" ValueChanged="sd_vol_ValueChanged" />
                <Button Canvas.Left="125" Canvas.Top="65" Content="Play" Height="35" Name="btn_play" Width="52" Click="btn_play_Click" />
                <Button Canvas.Left="183" Canvas.Top="77" Content="重播" Height="23" Name="btn_reset" Width="34" Click="btn_reset_Click" />
                <Button Canvas.Left="214" Canvas.Top="77" Content="下一曲" Height="23" Name="btn_next" Width="51" Click="btn_next_Click" />
                <Button Canvas.Left="32" Canvas.Top="77" Content="上一曲" Height="23" Name="btn_prev" Width="51" Click="btn_prev_Click" />
                <CheckBox Canvas.Left="89" Canvas.Top="81" Height="16" Name="cb_continue" Width="30" >
                    <Ellipse Height="10" Width="10" Stroke="Black" StrokeThickness="2" ></Ellipse>
                </CheckBox>
                <CheckBox Canvas.Left="281" Canvas.Top="84"  Height="16" Name="ck_vol" Width="25" Click="ck_vol_Click" IsThreeState="False" ClickMode="Release" ClipToBounds="False" Focusable="False" >
                    <Ellipse Height="10" Width="10" Stroke="Black" ></Ellipse>
                </CheckBox>
                <TextBlock Canvas.Left="175" Canvas.Top="101" Height="17" Name="txt_starttime" Text=""  TextAlignment="Right" Width="138" />
            </Canvas>
            <!--文件列表-->
            <DockPanel Grid.Row="1" LastChildFill="True">
                <ToolBar DockPanel.Dock="Top">
                    <Button Name="btn_open" Click="btn_open_Click">添加</Button>
                    <Button Name="btn_del" Click="btn_del_Click">删除</Button>
                    <Button Name="btn_start" Click="btn_start_Click">播放</Button>
                    <Button Name="btn_loadlrc" Click="btn_loadlrc_Click">加载歌词</Button>
                </ToolBar>
                <ListBox Name="lb_list" DisplayMemberPath="Filename"  Grid.Row="1" MouseDoubleClick="btn_start_Click">
                <ListBox.ContextMenu>
                    <ContextMenu >
                        <MenuItem Header="添加" Click="btn_open_Click" />
                        <MenuItem Header="删除" Click="btn_del_Click" />
                        <MenuItem Header="播放" Click="btn_start_Click" />
                    </ContextMenu>
                </ListBox.ContextMenu>
            </ListBox>
            </DockPanel>
            <!--右侧歌词-->
            <Grid ClipToBounds="True" Margin="20,50,20,50"  Grid.Column="1" Grid.Row="1">
                <TextBlock ClipToBounds="False"  Name="tb_lyric_old" TextAlignment="Center" TextWrapping="WrapWithOverflow" FontWeight="Bold" FontSize="18" VerticalAlignment="Top" ></TextBlock>
                <TextBox Grid.Column="1" Grid.Row="1"  ClipToBounds="False"  Name="tb_lyric" TextAlignment="Center" TextWrapping="WrapWithOverflow" FontWeight="Bold" FontSize="18" VerticalAlignment="Top" Foreground="DarkGreen"></TextBox>
            </Grid>
            <Rectangle Grid.Column="1" Grid.Row="1">
                <Rectangle.Fill>
                    <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                        <GradientStop Color="White" Offset="0" />
                        <GradientStop Color="White" Offset="1" />
                        <GradientStop Color="Transparent" Offset="0.475" />
                        <GradientStop Color="#C8FEFEFE" Offset="0.375" />
                        <GradientStop Color="#C8FFFFFF" Offset="0.575" />
                    </LinearGradientBrush>
                </Rectangle.Fill>
            </Rectangle>
            <!--分割线-->
            <!--<GridSplitter Grid.Column="0" Grid.Row="1"  Width="3" Background="Gray" />-->
        </Grid>

    </Grid>
</Window>

 

C#代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
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;
using System.ComponentModel;
using Microsoft.Win32;
using System.Windows.Threading;
using System.IO;
using System.Text.RegularExpressions;
using System.Windows.Media.Animation;

namespace Player
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        #region 保存文件信息用结构
        class finfo
        {
            public finfo(string name, string path) { Filename = name; Filepath = path; }
            public string Filename { set; get; }
            public string Filepath { set; get; }
            public List<lyricinfo> Lyric = new List<lyricinfo>();
        }
        class lyricinfo
        {
            public TimeSpan time;
            public string lrc;
        }
        #endregion

        //定义绑定用的List
        BindingList<finfo> list = new BindingList<finfo>();
        //定义Timer
        DispatcherTimer g_timer = new DispatcherTimer();
        //全局变量,是否暂停
        bool g_IsPause = true;
        //全局变量,当前曲目序号
        int g_index = -1;

        public MainWindow()
        {
            InitializeComponent();
            //绑定列表
            lb_list.ItemsSource = list;
            //绑定更新进度条的Timer
            g_timer.Interval = new System.TimeSpan(10);
            g_timer.Tick += new EventHandler(Progress_timer_Tick);
            //绑定音频结束时的事件
            mediaelement.MediaEnded += new RoutedEventHandler(mediaelement_MediaEnded);
        }
        //移动歌词
        private void MoveLyric()
        {
            //TranslateTransform mv = new TranslateTransform(0, tb_lyric.RenderTransform.Value.OffsetY - CalcY());
            //DoubleAnimation dbanimat= new DoubleAnimation();
            //dbanimat.By = -10;     //移动的大小
            //dbanimat.Duration = new System.Windows.Duration(TimeSpan.FromSeconds(0.5));
            //tb_lyric.RenderTransform = mv;   //绑定控件
            //mv.BeginAnimation(TranslateTransform.YProperty, dbanimat);
            tb_lyric.ScrollToLine(CalcY()); tb_lyric.LineDown();
        }
        //计算,歌词移动的Y坐标
        private int CalcY()
        {
            try
            {
                int i = 0;
                for (i = 1; i < list[g_index].Lyric.Count; ++i)
                {
                    TimeSpan lytime = list[g_index].Lyric[i].time;
                    TimeSpan pos = mediaelement.Position;
                    double diff = lytime.TotalSeconds / 10 - pos.TotalSeconds;
                    if (lytime.CompareTo(pos) > 0) break;
                }
                return i;
            }
            catch
            {
                return 0;
            }
        }
        //读取lrc文件
        private void ReadLyric(ref finfo f, string filelyric)
        {
            string lrc = File.ReadAllText(filelyric, System.Text.Encoding.GetEncoding("GB2312"));
            Regex rx = new Regex(@"(?<=^\[)(\d+:\d+\.\d+).(.+)(?=$)", RegexOptions.Multiline);
            //匹配表达式
            foreach (Match x in rx.Matches(lrc))
            {
                try
                {
                    //读取时间
                    TimeSpan ti = new TimeSpan(0, int.Parse(x.Value.Substring(0, 2)),
                                            int.Parse(x.Value.Substring(3, 2)));//int.Parse(x.Value.Substring(6, 2))
                    //读取歌词
                    string ly = x.Value.Substring(9);
                    f.Lyric.Add(new lyricinfo() { time = ti, lrc = ly });
                }
                catch
                {
                    //continue;
                }
            }
        }
        //设置UI
        private void SetUI(bool start)
        {
            //start==true,设为播放状态
            //start==false,设为暂停
            //if (!mediaelement.HasAudio) return;//没有音频时不执行代码
            g_timer.IsEnabled = start;  //设置Timer
            btn_play.Content = start ? "Pause" : "Play";    //设置按钮标题
            g_IsPause = !start;     //设置全局标记:[是否暂停中]
        }
        //设置播放信息,并播放文件
        private void SetSource()
        {
            //取文件信息
            var obj = lb_list.SelectedItem as finfo;
            if (obj == null) return;

            //打开文件
            mediaelement.Source = new Uri(obj.Filepath);
            //设置歌词
            string lrc = "\n\n\n\n\n\n\n\n\n\n";
            if (obj.Lyric.Count > 0)
            {
                foreach (var x in obj.Lyric) { lrc = string.Concat(lrc + x.lrc + '\n'); }
            }
            lrc = string.Concat(lrc + "\n\n\n\n\n\n\n\n\n\n");
            tb_lyric.Text = lrc;
            //设置标题
            txt_title.Text = obj.Filename;
            //保存当前曲目序号
            g_index = lb_list.SelectedIndex;
            //开始播放
            mediaelement.Play();
            //设置界面
            SetUI(true);

        }
        #region 开始、暂停、重播
        /// <summary>
        /// 播放按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_play_Click(object sender, RoutedEventArgs e)
        {
            //列表为空时,调用[打开文件]
            if (list.Count <= 0) { btn_open_Click(this, null); return; }
            //开始或暂停播放
            if (g_IsPause) { mediaelement.Play(); }
            else { mediaelement.Pause(); }
            //设置界面
            SetUI(g_IsPause);
        }
        /// <summary>
        /// 重播按钮
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_reset_Click(object sender, RoutedEventArgs e)
        {
            if (!mediaelement.HasAudio) return;
            mediaelement.Stop();
            //开始播放
            SetUI(true);
            mediaelement.Play();
        }
        #endregion
        #region 上一曲、下一曲、自动下一曲
        /// <summary>
        /// 播放上一曲
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_prev_Click(object sender, RoutedEventArgs e)
        {
            int index = g_index - 1;
            //判断是否有上一曲
            if (index >= 0 && index < list.Count)
            {
                lb_list.SelectedIndex = index;
                SetSource();
            }
        }
        /// <summary>
        /// 播放下一曲
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_next_Click(object sender, RoutedEventArgs e)
        {
            int index = g_index + 1;
            //判断是否有上一曲
            if (index >= 0 && index < list.Count)
            {
                lb_list.SelectedIndex = index;
                SetSource();
            }
        }
        /// <summary>
        /// 自动下一曲
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void mediaelement_MediaEnded(object sender, RoutedEventArgs e)
        {
            if (cb_continue.IsChecked != true) return;
            //播放下一曲
            btn_next_Click(this, null);
        }
        #endregion
        #region 音量设置
        /// <summary>
        /// 修改音量
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void sd_vol_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            //设置音量
            mediaelement.Volume = e.NewValue / 10;
        }
        /// <summary>
        /// 设置静音
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ck_vol_Click(object sender, RoutedEventArgs e)
        {
            mediaelement.IsMuted = (bool)ck_vol.IsChecked;
        }
        #endregion
        #region 添加、删除、播放、加载歌词
        /// <summary>
        /// 添加文件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_open_Click(object sender, RoutedEventArgs e)
        {
            OpenFileDialog dlg = new OpenFileDialog();
            dlg.Filter = "音频格式(*.mp3,*.wav)|*.mp3;*.wav";
            dlg.Multiselect = true;
            if (dlg.ShowDialog() != true) return; //不为确定时返回

            for (int i = 0; i < dlg.FileNames.Length; ++i)
            {
                finfo newfile = new finfo(dlg.SafeFileNames[i], dlg.FileNames[i]);
                //是否有歌词文件
                string filelyric = dlg.FileNames[i].Remove(dlg.FileNames[i].Length - 4) + ".lrc";
                //加载歌词
                if (File.Exists(filelyric)) { ReadLyric(ref newfile, filelyric); }
                //添加到列表
                list.Add(newfile);
            }

            lb_list.SelectedIndex = (list.Count - 1);

            if (g_IsPause)
            {
                //设置并播放文件
                SetSource();
            }
        }
        /// <summary>
        /// 删除文件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_del_Click(object sender, RoutedEventArgs e)
        {
            int index = lb_list.SelectedIndex;
            if (index < 0) return;
            //移除选定元素
            list.RemoveAt(index);
            //如果删除的是当前歌曲,播放下一曲
            if (lb_list.SelectedIndex == g_index) btn_next_Click(this, null);
        }
        /// <summary>
        /// 播放文件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_start_Click(object sender, RoutedEventArgs e)
        {
            if (list.Count <= 0) return;
            if (mediaelement.HasAudio) mediaelement.Stop();
            SetSource();
        }
        /// <summary>
        /// 添加歌词文件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_loadlrc_Click(object sender, RoutedEventArgs e)
        {
            if (list.Count <= 0) return;
            OpenFileDialog dlg = new OpenFileDialog();
            dlg.Filter = "歌词文件(*.lrc)|*.lrc";
            if (dlg.ShowDialog() != true) return;

            //打开歌词文件
            finfo gfifo = list[g_index];
            ReadLyric(ref gfifo, dlg.FileName);

            //设置歌词
            string lrc = "\n\n\n\n\n\n\n\n\n\n";
            if (gfifo.Lyric.Count > 0)
            {
                foreach (var x in gfifo.Lyric) { lrc = string.Concat(lrc + x.lrc + '\n'); }
            }
            lrc = string.Concat(lrc + "\n\n\n\n\n\n\n\n\n\n");
            tb_lyric.Text = lrc;
        }


        #endregion
        #region 进度条
        /// <summary>
        /// 计时器,更新进度条
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void Progress_timer_Tick(object sender, EventArgs e)
        {
            //得到播放进度
            if (!mediaelement.HasAudio) return;
            try
            {
                TimeSpan ts = mediaelement.Position;
                TimeSpan max = mediaelement.NaturalDuration.TimeSpan;
                //计算进度百分比
                double pos = ts.TotalSeconds / max.TotalSeconds * 100;
                //格式化字符串
                string timepos = string.Format("{0}/{1}", ts.ToString("hh':'mm':'ss"), max.ToString("hh':'mm':'ss"));
                //更新进度
                sd_pos.Value = pos;
                txt_starttime.Text = timepos;
                //显示歌词
                if (list[g_index].Lyric.Count > 0) MoveLyric();
            }
            catch
            {
                //MessageBox.Show(ex.Message);
            }
        }
        /// <summary>
        /// 拖动进度条,改变文件进度,处理鼠标按下和弹起事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void sd_pos_ui_MouseDown(object sender, MouseButtonEventArgs e)
        {
            g_timer.IsEnabled = false;
        }
        private void sd_pos_ui_MouseUp(object sender, MouseButtonEventArgs e)
        {
            if (!mediaelement.HasAudio) return;
            //计算相应时间

            TimeSpan max = mediaelement.NaturalDuration.TimeSpan;
            double per = sd_pos.Value / 100;
            TimeSpan pos = TimeSpan.FromSeconds(max.TotalSeconds * per);
            //设置进度
            mediaelement.Position = pos;
            g_timer.IsEnabled = true;
        }
        #endregion
    }
}



 

 

  • 9
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
### 回答1: WPF NVR(Windows Presentation Foundation Network Video Recorder)是一种基于WPF(Windows Presentation Foundation)技术开发的网络视频录像机播放器。它是一款适用于Windows操作系统的软件,主要用于播放网络视频录像机(NVR)中的录像文件。 WPF NVR播放器具有多种功能和特点。首先,它支持多种音视频格式的播放,包括常见的MP4、AVI、WMV等格式,无论是网络摄像头还是NVR设备中的录像文件,都可以通过WPF NVR播放器进行播放和回放。 其次,WPF NVR播放器提供了强大的可视化界面,具有用户友好的操作界面和直观的控制面板,用户可以方便地对录像进行播放、暂停、快进、后退等操作,同时还可以调整音量和视频画面的亮度、对比度等参数。 此外,WPF NVR播放器还支持时间轴的显示和操作,用户可以通过时间轴直观地选择播放的时间段,实现录像的精准回放。同时,WPF NVR播放器还提供了截图功能,用户可以随时截取当前播放画面,并保存为图片文件。 最后,WPF NVR播放器还支持网络视频的直播功能,用户可以通过网络与NVR设备进行实时视频传输,实现远程监控和查看网络摄像头的画面。这使得WPF NVR播放器成为一款功能强大、应用广泛的视频播放器。 综上所述,WPF NVR播放器是一款基于WPF技术开发的网络视频录像机播放器,具有多种功能和特点,可以方便地播放和回放网络视频录像机的录像文件,同时还支持画面调整、时间轴操作、截图和直播等功能。 ### 回答2: WPF NVR播放器指的是使用WPF(Windows Presentation Foundation)技术开发的网络视频录像机播放器。它是一种功能强大的软件,能够在计算机上播放网络视频录像机的录像文件。 WPF NVR播放器具有以下特点和功能: 1. 支持多种视频格式:WPF NVR播放器可以播放多种常见的视频格式,如MP4、AVI、MOV等,用户可以根据需要选择不同的视频格式来播放。 2. 高清播放体验:WPF NVR播放器支持高清视频播放,能够提供细腻、清晰的画面,使用户可以更好地观看录像。 3. 强大的视频控制功能:WPF NVR播放器具备多种视频控制功能,如播放、暂停、快进、倒放等,用户可以根据需要随时对视频进行控制。 4. 时间轴回放:WPF NVR播放器提供了时间轴回放功能,用户可以根据时间轴选择要播放的录像片段,方便快速定位和观看。 5. 视频截图功能:WPF NVR播放器支持视频截图功能,用户可以随时截取当前播放的画面并保存为图片,在需要的时候进行查看或分享。 6. 个性化设置:WPF NVR播放器提供了个性化设置选项,用户可以根据自己的需求,调整播放器的界面和功能设置,以达到更好的使用体验。 总的来说,WPF NVR播放器具有功能强大、方便实用的特点,适用于需要在计算机上观看网络视频录像机录像的场景,提供了高清播放、时间轴回放、视频控制等多种功能,能够满足用户对于视频播放的各种需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值