using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace BaiduYun
{
    public partial class M3u8Player : Form
    {


        #region 导出函数

        [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
        private static extern IntPtr libvlc_new(int argc, string[] argv);

        [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
        private static extern IntPtr libvlc_media_new_path(IntPtr pInstance, string path);

        [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
        private static extern IntPtr libvlc_media_player_new_from_media(IntPtr pMedia);

        // 设置图像输出的窗口
        [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
        private static extern void libvlc_media_player_set_hwnd(IntPtr pPlayer, Int32 hWnd);

        [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
        private static extern int libvlc_media_player_play(IntPtr pPlayer);

        [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
        private static extern void libvlc_media_player_stop(IntPtr pPlayer);

        [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
        private static extern void libvlc_release(IntPtr pInstace);

        [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
        public static extern void libvlc_media_release(IntPtr libvlc_media_inst);

        [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
        private static extern void libvlc_media_player_pause(IntPtr libvlc_mediaplayer);

        [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
        public static extern void libvlc_media_player_release(IntPtr libvlc_mediaplayer);

        // 解析视频资源的媒体信息(如时长等)
        [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
        public static extern void libvlc_media_parse(IntPtr libvlc_media);

        // 返回视频的时长(必须先调用libvlc_media_parse之后，该函数才会生效)
        [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
        public static extern Int64 libvlc_media_get_duration(IntPtr libvlc_media);

        // 当前播放的时间
        [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
        public static extern Int64 libvlc_media_player_get_time(IntPtr libvlc_mediaplayer);

        // 设置播放位置(拖动)
        [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
        public static extern void libvlc_media_player_set_time(IntPtr libvlc_mediaplayer, Int64 time);

        // 获取和设置音量
        [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
        public static extern int libvlc_audio_get_volume(IntPtr libvlc_media_player);
        [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
        public static extern void libvlc_audio_set_volume(IntPtr libvlc_media_player, int volume);

        // 设置全屏
        [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
        public static extern void libvlc_set_fullscreen(IntPtr libvlc_media_player, bool isFullScreen);

        //获取和改变播放速率  流媒体可用 1为正常速度
        [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
        public static extern float libvlc_media_player_get_rate(IntPtr libvlc_media_player);
        [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
        public static extern int libvlc_media_player_set_rate(IntPtr libvlc_media_player, float rate);

        //获取和改变播放进度  流媒体可用
        [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
        public static extern void libvlc_media_player_set_position(IntPtr libvlc_media_player, float f_pos);
        [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
        public static extern float libvlc_media_player_get_position(IntPtr libvlc_media_player);

        //获取播放状态
        [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
        public static extern int libvlc_media_player_get_state(IntPtr libvlc_media_player);

        //截屏
        [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
        public static extern int libvlc_video_take_snapshot(IntPtr libvlc_media_player, int num, string path, int width, int height);

        [DllImport("libvlc", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
        public static extern Int64 libvlc_media_player_get_chapter(IntPtr libvlc_media_player);

        #endregion

        #region 播放器变量

        private IntPtr pInstance;
        private IntPtr pMedia;
        private IntPtr pPlayer;
        private bool bPlaying;

        double TotalTime = 0;

        #endregion

        public M3u8Player()
        {
            InitializeComponent();
        }

        private void M3u8Player_Load(object sender, EventArgs e)
        {
            PlayM3u8();
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            if (bPlaying)
            {
                if (TimeBar.Value == TimeBar.Maximum)
                {
                    libvlc_media_player_stop(pPlayer);
                    timer1.Stop();
                }
                else
                {
                    TimeBar.Value = (int)(libvlc_media_player_get_position(pPlayer) * TotalTime);
                    TimeSpan.Text = string.Format("{0}/{1}",
                        GetTimeString((int)(libvlc_media_player_get_position(pPlayer) * TotalTime)),
                        GetTimeString(TimeBar.Maximum));
                }
            }
        }//每1s修改播放进度

        public void PlayM3u8()
        {
            StreamReader sr = new StreamReader("temp.m3u8", Encoding.Default);

            Regex pattern = new Regex(@"EXTINF:([\w\W]+?),([\w\W]+?)#");
            MatchCollection matchsMade = pattern.Matches(sr.ReadToEnd());
            int i = 0;
            TotalTime = 0;
            foreach (Match item in matchsMade)
            {
                TotalTime = TotalTime + Convert.ToDouble(item.Groups[1].Value);
                i++;
            }
            TimeBar.Maximum = (int)Math.Floor(TotalTime);

            if (bPlaying == true)
            {
                libvlc_media_player_stop(pPlayer);
            }

            string[] argv = new string[] { 
                "--ignore-config"
            };
            pInstance = libvlc_new(argv.Length, argv);
            pMedia = libvlc_media_new_path(pInstance, "temp.m3u8");
            pPlayer = libvlc_media_player_new_from_media(pMedia);
            libvlc_media_player_set_hwnd(pPlayer, (Int32)panel1.Handle);

            libvlc_media_player_play(pPlayer);
            bPlaying = true;

            timer1.Enabled = true;
        }//播放根目录下temp.m3u8文件

        private string GetTimeString(int val)
        {
            int hour = val / 3600;
            val %= 3600;
            int minute = val / 60;
            int second = val % 60;
            return string.Format("{0:00}:{1:00}:{2:00}", hour, minute, second);
        }//由秒转换为标准格式时间

        private void button4_Click(object sender, EventArgs e)
        {
            if (bPlaying)
                libvlc_video_take_snapshot(pPlayer, 0, "temp.jpg", 600, 480);
        }

        private void btn_play_Click(object sender, EventArgs e)
        {
            if (bPlaying)
            {
                TimeBar.Value = 0;
                libvlc_media_player_stop(pPlayer);
                libvlc_media_release(pMedia);
                libvlc_release(pPlayer);
                bPlaying = false;
                this.Dispose();
            }
        }

        private void TimeBar_Scroll(object sender, EventArgs e)
        {
            TimeSpan.Text = string.Format("{0}/{1}",
            GetTimeString(TimeBar.Value),
            GetTimeString(TimeBar.Maximum));
        }//当移动时间轴时 改变时间显示

        private void TimeBar_MouseUp(object sender, MouseEventArgs e)
        {
            timer1.Enabled = true;
            if (bPlaying)
            {
                libvlc_media_player_set_position(pPlayer, (float)TimeBar.Value / (float)TimeBar.Maximum);
            }
        }//松开时间轴  根据目标进度跳转

        private void TimeBar_MouseDown(object sender, MouseEventArgs e)
        {
            timer1.Enabled = false;
        }//按下时间轴

        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (bPlaying)
                libvlc_media_player_set_rate(pPlayer, (float)Convert.ToDouble(comboBox1.SelectedItem));
        }

        private void M3u8Player_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (bPlaying)
            {
                TimeBar.Value = 0;
                libvlc_media_player_stop(pPlayer);
                libvlc_media_release(pMedia);
                libvlc_release(pPlayer);
                bPlaying = false;
                this.Dispose();
            }
        }
    }
}
