using ABI.System;
using Microsoft.VisualBasic;
using Microsoft.VisualBasic.FileIO;
using Newtonsoft.Json.Linq;
using System;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Reflection.Metadata;
using System.Runtime.InteropServices;
using System.Security.Policy;
using System.Text;
using System.Text.Json;
using System.Text.RegularExpressions;
using System.Timers;
using System.Windows.Forms;
using System.Xml.Linq;
using Windows.Storage;
using WinFormsApp1;


namespace DragonVideoPlayer
{
   
    
    public class MainForm : Form
    {    //↓ミニプレイヤーをマウスで動かすのに使う
        [DllImport("user32.dll")]
        private static extern bool ReleaseCapture();

        [DllImport("user32.dll")]
        private static extern IntPtr SendMessage(
            IntPtr hWnd,
            int Msg,
            int wParam,
            int lParam);

        private const int WM_NCLBUTTONDOWN = 0xA1;
        private const int HTCAPTION = 0x2;
        private bool _isMiniPlayer = false;

        private bool _isVr360Mode = false;
        private int fov_360 = 90;
        private bool vr360Dirty = false;
        private System.Windows.Forms.Timer vr360Timer;
        private int roll_360 = 0;
        private int yaw_360 = 0;
        private int pitch_360 = 0;
        private int step_360 = 5; // 1回の移動量（調整可）
        XDocument doc_animenosekai_epg;
        XDocument doc_karenda_epg;
        XDocument doc_jp_epg_26f0ce;
        XDocument doc_radiko_epg;
        double lastPos = -1;
        DateTime abema_cm_reload_lastMoveTime = DateTime.Now;

        private System.Windows.Forms.Timer abemaTV_cm_reaload_Timer;
        private System.Windows.Forms.Timer m3u8_title_replace_Timer;

        private double _currentSubDelay = 0;
        // mini化前のフォーム状態を保存
        private Rectangle _prevMiniBounds;
        private FormBorderStyle _prevMiniBorderStyle;
        private FormWindowState _prevMiniWindowState;


        bool _mute_bool = false;

        private NotifyIcon trayIcon;
        private ContextMenuStrip trayMenu;

        private MenuStrip capter_menuStrip;
        private ToolStripMenuItem menuChapters;
        //public PictureBox loadingGif;

        private double audio_delay = 0;
        private int list_type = 0;
        private double _currentSpeed = 1.0;
        private double _subsize = 1.0;
        private int _sub_pos_y = 100;
        private System.Windows.Forms.Timer _a_b_loopTimer;
        private double _a_maker;
        private double _b_maker;
        private String _title = "";
        private int _volume = 100;
        bool _a_b_isLooping = false;
        ToolStripMenuItem menuAudio;
        ToolStripMenuItem menuSub;
        private int cap_size = 0;
        private int cap_position = 0;
        private bool youtube_playlist_bool = false;

        private double nokori_jikan;
        internal Panel videoPanel;
        internal TrackBar PositionSlider;
        internal TrackBar volume_Slider;
        internal TrackBar ListSlider;
        internal TrackBar Speed_Slider;
        internal Label lblTime;
        internal Label lblResolution;
        internal Label lblFilesize;
        internal Label lbl_Listsize;
        internal Label lbl_title;
        internal Label lbl_category;
        internal Label lbl_desc;
        internal Label lbl_list_name;
        internal Label volume_label;
        internal Label speed_label;
   
        private System.Windows.Forms.Timer _frameStepTimer;
        private System.Windows.Forms.Timer _frameBackStepTimer;

        private MenuBuilder _menuBuilder;

        private bool _isFullScreen = false;

        internal FormWindowState _prevWindowState;
        internal FormBorderStyle _prevBorderStyle;


        private bool _list_slidr_isDragging = false;
        private bool _pos_slidr_isDragging = false;

        private string argument;

        private double _m3u8_timePos = 0;

        private double _duration = 0;


        private ToolStripTextBox searchBox;
        private ToolStripButton searchButton;
        private ToolStripMenuItem resultMenu;

        private string currentFilePath = "";


        private double _videoWidth;
        private double _videoHeight;
        private double _filesize;


        // IPC用

        private Thread _readThread;

        private double _timePos = 0;

        internal Panel BottomControlPanel;


        private VideoState _videoState = new VideoState();
        //グローバル変数
        private List<String> folder_movie_lists;
        private List<String> main_video_lists;
        private List<String> abema_stream_lists;

    
     



        private List<String> search_lists;

        private List<String> OverClocked_remix_lists;


        private List<String> mov3_lists;
        private List<String> fast_lists;
        private List<String> rakuten_lists;
        private List<String> youtube_play_lists_url;

        private List<String> zhon_lists;
        private List<String> akariko_lists;
      
 
        private List<String> youtube_play_lists_title;

        private List<String> db_all_video_lists;
        private int main_video_count;
        
        internal System.Windows.Forms.Timer _seekTimer;
        internal System.Windows.Forms.Timer _prevseekTimer;
        internal System.Windows.Forms.Timer _next_movie_Timer;
        internal System.Windows.Forms.Timer _prev_movie_Timer;
        internal System.Windows.Forms.Timer _speed_up_Timer;
        internal System.Windows.Forms.Timer _speed_down_Timer;
        internal System.Windows.Forms.Timer _flame_step_Timer;
        internal System.Windows.Forms.Timer _flame_back_step_Timer;

        internal System.Windows.Forms.Timer _cap_next_Timer;
        internal System.Windows.Forms.Timer _cap_back_Timer;


        private MpvPlayer _myplayer;





        internal TableLayoutPanel _mainLayout;
        internal MenuStrip TopMenuPanel;
        public MainForm()
        {
            doc_animenosekai_epg=new XDocument();
            doc_karenda_epg = new XDocument() ;
             doc_jp_epg_26f0ce = new XDocument() ;
          doc_radiko_epg = new XDocument() ;
            abemaTV_cm_reaload_Timer = new System.Windows.Forms.Timer();
   

            m3u8_title_replace_Timer = new System.Windows.Forms.Timer();

            System.IO.Directory.SetCurrentDirectory(Application.StartupPath);
                OverClocked_remix_lists = new List<string>();
               folder_movie_lists = new List<string>();
        main_video_lists = new List<string>();
       abema_stream_lists = new List<string>();




            search_lists = new List<string>();

         OverClocked_remix_lists = new List<string>();
            zhon_lists = new List<string>();
        
            akariko_lists = new List<string>();
            
            mov3_lists = new List<string>();
         fast_lists = new List<string>();
         
            rakuten_lists = new List<string>();
        youtube_play_lists_url = new List<string>();

      youtube_play_lists_title = new List<string>();

            db_all_video_lists = new List<string>();
            _a_b_loopTimer = new System.Windows.Forms.Timer();
            _a_b_loopTimer.Interval = 100; // 0.1秒ごとチェック
            _a_b_loopTimer.Tick += a_b_LoopTimer_Tick;
            list_type = 0;
            nokori_jikan = 1;
            this.Icon = new Icon("icon.ico");
            this.AllowDrop = true;
            this.Text = "Dragon Video Player";
            this.Width = 800;
            this.Height = 600;
            this.MinimumSize = new Size(200, 100);
            if (config_class.config_int_read("起動時のウインドウサイズ") == 1)
            {
                try
                {
                    if (!string.IsNullOrWhiteSpace(config_class.config_text_read("起動時のwidth")) &&
                        !string.IsNullOrWhiteSpace(config_class.config_text_read("起動時のheight")))
                    {

                        this.Width = int.Parse(config_class.config_text_read("起動時のwidth"));
                        this.Height = int.Parse(config_class.config_text_read("起動時のheight"));
                      
                    }
                }
                catch (System.Exception ex)
                {
                    error.write_error_log(ex.Message + ex.StackTrace);
                    Debug.WriteLine("config読み込みでエラー：" + ex.Message);
                }




            }
            if (config_class.config_int_read("起動時のウインドウサイズ") == 2)
            {
                try
                {
                    if (!string.IsNullOrWhiteSpace(config_class.config_text_read("復元width")) &&
                        !string.IsNullOrWhiteSpace(config_class.config_text_read("復元height")))
                    {

                        this.Width = int.Parse(config_class.config_text_read("復元width"));
                        this.Height = int.Parse(config_class.config_text_read("復元height"));
                     
                    }
                }
                catch (System.Exception ex)
                {
                    error.write_error_log(ex.Message + ex.StackTrace);
                    Debug.WriteLine("config読み込みでエラー：" + ex.Message);
                }
                //復元
            }
            if (config_class.config_int_read("起動時のウインドウサイズ") == 3)
            {
                this.Width = Screen.GetBounds(this).Width;
                this.Height = Screen.GetBounds(this).Height;
                this.WindowState = FormWindowState.Maximized;
                //最大化
            }

           
         


            InitializeUI();

         



                capter_menuStrip = new MenuStrip();



            this.FormClosing += new FormClosingEventHandler(formClosing);
            this.DragEnter += Form1_DragEnter;
            this.DragDrop += Form1_DragDrop;
            this.Load += Form1_Load;
          
         
            this.KeyDown += Form1_KeyDown;
            videoPanel.MouseDown += VideoPanel_MouseDown;
          
            this.Resize+= Form1_Resize;


            this.FormClosing += close;

            this.KeyPreview = true;
            this.MouseWheel += Form1_MouseWheel;
            videoPanel.CreateControl();
            _myplayer = new MpvPlayer(videoPanel.Handle);

            _myplayer.MpvMessageReceived += HandleMpvMessage;

            volume_Slider.Scroll += trackBarVolume_Scroll;

            Speed_Slider.Scroll += trackBarSpeed_Scroll;


            _frameStepTimer = new System.Windows.Forms.Timer();
            _frameStepTimer.Interval = 80; // 30msごと（好みで調整）
            _frameStepTimer.Tick += (s, e) =>
            {

                FrameStep();
            };
            _frameBackStepTimer = new System.Windows.Forms.Timer();
            _frameBackStepTimer.Interval = 80; // 30msごと（好みで調整）
            _frameBackStepTimer.Tick += (s, e) =>
            {

                FrameBackStep();
            };
            if (config_class.config_bool_read("タスクトレイに常駐") == true)
            {
                InitTray();
            }

            vr360Timer = new System.Windows.Forms.Timer();
            vr360Timer.Interval = 16; // 約60fps
            vr360Timer.Tick += (s, e) =>
            {
                if (!vr360Dirty) return;

                vr360Dirty = false;
                UpdateVRView();
            };
            vr360Timer.Start();

            if (config_class.config_bool_read("フルスクリーン") == true)
            {
                ToggleFullScreen();
            }

        }

        private void Form1_Resize(object sender, EventArgs e)
        {
            if (WindowState == FormWindowState.Minimized)
            {
                bool trayEnabled = config_class.config_bool_read("タスクトレイに常駐");

                if (trayEnabled)
                {
                    Hide(); // トレイに隠す
                }
                else
                {
                    ShowInTaskbar = true; // 普通にタスクバーへ
                }
            }
        }

        private void VideoPanel_MouseDown(object sender, MouseEventArgs e)
        {
            if (_isMiniPlayer && e.Button == MouseButtons.Left)
            {
                ReleaseCapture();
                SendMessage(this.Handle, WM_NCLBUTTONDOWN, HTCAPTION, 0);

            }
           

        }
        public void ToggleMiniPlayer()
        {


            if (!_isMiniPlayer)
                EnterMiniPlayer();
            else
                ExitMiniPlayer();
        }


        public void vr_360mode()
        {

            if (!_isVr360Mode)
            {
                _myplayer.Video.vr360_mode_enable();
                _isVr360Mode = true;
            }
            else
            {
                _myplayer.Video.vf_normal();
                _isVr360Mode = false;
            }
               
        }
        private void EnterMiniPlayer()
        {

            // フルスクリーン中なら解除してから
            if (_isFullScreen)
                ToggleFullScreen();

            _prevMiniBounds = this.Bounds;
            _prevMiniBorderStyle = this.FormBorderStyle;
            _prevMiniWindowState = this.WindowState;

            // レイアウトの上下UIを消す
            _mainLayout.RowStyles[0].Height = 0;
            _mainLayout.RowStyles[2].Height = 0;

            TopMenuPanel.Visible = false;
            BottomControlPanel.Visible = false;
            capter_menuStrip.Visible = false;

            FormBorderStyle = FormBorderStyle.None;
            TopMost = true;
            WindowState = FormWindowState.Normal;

            Size = new Size(480, 270);

            var area = Screen.FromControl(this).WorkingArea;
            Location = new Point(
                area.Right - Width - 16,
                area.Bottom - Height - 16
            );

            _isMiniPlayer = true;
        }


        private void ExitMiniPlayer()
        {
            this.Bounds = _prevMiniBounds;
            this.FormBorderStyle = _prevMiniBorderStyle;
            this.WindowState = _prevMiniWindowState;

            _mainLayout.RowStyles[0].SizeType = SizeType.AutoSize;
            _mainLayout.RowStyles[2].SizeType = SizeType.AutoSize;

            TopMenuPanel.Visible = true;
            BottomControlPanel.Visible = true;
            capter_menuStrip.Visible = true;

            TopMost = false;

            _isMiniPlayer = false;
        }
     
      protected override void OnResize(EventArgs e)
        {
            base.OnResize(e);
            if (config_class.config_bool_read("タスクトレイに常駐"))
            {
                if (WindowState == FormWindowState.Minimized)
                {
                    Hide();
                }
            }
            
        }

        //public void saishou()
        //{
        //    WindowState = FormWindowState.Normal;
        //}
        private void InitTray()
        {
            trayMenu = new ContextMenuStrip();

            trayMenu.Items.Add("最大化", null, (s, e) =>
            {
                Show();
                WindowState = FormWindowState.Normal;
                Activate();
            });

            trayMenu.Items.Add("最小化", null, (s, e) =>
            {
                WindowState = FormWindowState.Minimized;
            });
            trayMenu.Items.Add("フルスクリーン", null, (s, e) =>
            {
                ToggleFullScreen();
            });
            trayMenu.Items.Add("ミニプレイヤー", null, (s, e) =>
            {
                ToggleMiniPlayer();
            });
            trayMenu.Items.Add("閉じる", null, (s, e) =>
                {
                    trayIcon.Visible = false;
                    Application.Exit();
                });

            trayIcon = new NotifyIcon
            {
                Icon = this.Icon,
                Text = "mpv Player",
                Visible = true,
                ContextMenuStrip = trayMenu
            };


            trayIcon.DoubleClick += (s, e) =>
            {

                if (Visible && WindowState != FormWindowState.Minimized)
                {
                    Hide();
                }
                else
                {
                    Show();
                    WindowState = FormWindowState.Normal;
                    Activate();
                }

            };
           
        }
        // ================= UI =================

        void InitializeUI()
        {

            List<string> history_list = new List<string>();
            rakuten_lists = new List<string>();
            history_list = sql_class.sql_history(config_class.config_int_read("履歴数"));

            search_lists = new List<string>();

            List<string> ranking_list = new List<string>();
            ranking_list = sql_class.sql_ranking(config_class.config_int_read("ランキング数"));
            string db = Path.Combine(AppContext.BaseDirectory, "abema.txt");

            abema_stream_lists = TextListLoader.Load("abema.txt");
     
            mov3_lists = TextListLoader.Load("mov3.txt");
            fast_lists = TextListLoader.Load("fast.txt");

         
          

            zhon_lists = TextListLoader.Load("zhongying.txt");
            rakuten_lists= TextListLoader.Load("rakuten.txt");
            akariko_lists = TextListLoader.Load("akariko.txt");
            UIBuilder.Build(this, abema_stream_lists,mov3_lists, fast_lists, history_list, 
                ranking_list, rakuten_lists,zhon_lists, akariko_lists);
            var searec_menuStrip = new MenuStrip();
            if (config_class.config_bool_read("検索窓を有効") == true)
            {


                // 検索ボックス
                searchBox = new ToolStripTextBox();
                searchBox.Width = 200;

                // 検索ボックス
                searchBox = new ToolStripTextBox();
                searchBox.Width = 200;

                // 検索ボタン
                searchButton = new ToolStripButton("検索");
                searchButton.Click += SearchButton_Click;

                // 検索結果メニュー（ここに追加される）
                resultMenu = new ToolStripMenuItem("検索結果");

                // Menuに追加
                searec_menuStrip.Items.Add(new ToolStripLabel("検索: "));
                searec_menuStrip.Items.Add(searchBox);
                searec_menuStrip.Items.Add(searchButton);
                searec_menuStrip.Items.Add(resultMenu);

                this.MainMenuStrip = searec_menuStrip;
                this.Controls.Add(searec_menuStrip);
            }

        }


       
        void formClosing(object sender, FormClosingEventArgs e)
        {
            StopMpv();



            config_class.save_config_file("復元width", this.Width.ToString());
            config_class.save_config_file("復元height", this.Height.ToString());
        }
        public void stats_script_binding(String page)
        {
            _myplayer.stats_script_binding(page);
        }
        public void search_youtube_func()
        {

            string result = Interaction.InputBox(
    "検索キーワードを入力してください",
    "検索ダイアログ",
    ""
);

            if (!string.IsNullOrEmpty(result))
            {

                StartMpv($"ytdl://ytsearch100:{result}");
                list_youtube_playlist();
            }

            list_youtube_playlist();


        }
        public void search_func()
        {

            string result = Interaction.InputBox(
    "検索キーワードを入力してください",
    "検索ダイアログ",
    ""
);

            if (!string.IsNullOrEmpty(result))
            {
                if (config_class.config_bool_read("検索窓を有効") == true)
                {

                    search_lists = sql_class.sql_kensaku(result, config_class.config_int_read("動画DBのソート"), config_class.config_int_read("動画DBのソートの順序"), 200, 0);

                    ShowResults(search_lists);
                }
                search_lists = sql_class.sql_kensaku(result, config_class.config_int_read("動画DBのソート"), config_class.config_int_read("動画DBのソートの順序"));


            }
            list_seach();
        }
        public void search_youtube_bt_click(String keyword)
        {

            if (string.IsNullOrEmpty(keyword))
            {
                return;
            }



            StartMpv($"ytdl://ytsearch100:{keyword}");

            list_youtube_playlist();


        }
        private void ShowResults(List<string> results)
        {
            resultMenu.DropDownItems.Clear();

            foreach (var path in results)
            {
                var item = new ToolStripMenuItem(Path.GetFileName(path));

                // クリックで再生
                item.Click += (s, e) =>
                {
                    StartMpv(path);
                };

                resultMenu.DropDownItems.Add(item);
            }
        }

        private void SearchButton_Click(object sender, EventArgs e)
        {
            string keyword = searchBox.Text;

            search_lists = sql_class.sql_kensaku(keyword, config_class.config_int_read("動画DBのソート"), config_class.config_int_read("動画DBのソートの順序"), 200, 0);

            ShowResults(search_lists);
        }


        private async void Form1_Load(object sender, EventArgs e)
        {



            if (config_class.config_bool_read("ボリュームを保存") == true)
            {

                if (!string.IsNullOrEmpty(config_class.config_text_read("ボリューム数")))
                {

                    String vol_st = config_class.config_text_read("ボリューム数");
                    volume_label.Text = vol_st;
                    if (int.TryParse(vol_st, out int vol_int))
                    {
                        _volume = vol_int;

                        if (volume_Slider.Maximum >= vol_int)
                            volume_Slider.Value = vol_int;


                    }
                }


            }

            youtube_play_lists_url = new List<string>();


            youtube_play_lists_title = new List<string>();
            folder_movie_lists = new List<string>();
            main_video_lists = new List<string>();



            db_all_video_lists = new List<string>();



            main_video_count = 0;
            string[] cmds = null;
            try
            {
                cmds = System.Environment.GetCommandLineArgs();
            }
            catch (System.Exception ex)
            {
                error.write_error_log(ex.Message + ex.StackTrace);
                Debug.WriteLine(ex.Message + ex.StackTrace);


            }

            if (cmds != null)
            {
                try
                {

                    if (cmds.Length == 1)
                    {
                        currentFilePath = config_class.config_text_read("url");
                    }
                    if (cmds.Length > 1)
                    {
                        String kidou_path = cmds[1];
                        currentFilePath = kidou_path;
                        start_list_update(kidou_path);

                        if (System.IO.File.Exists(kidou_path))
                        {
                            if (System.Text.RegularExpressions.Regex.IsMatch(kidou_path, config_class.config_text_read("動画取得の拡張子の正規表現"), System.Text.RegularExpressions.RegexOptions.IgnoreCase))
                            {
                                StartMpv(kidou_path);

                            }

                        }
                    }
                }
                catch (System.Exception ex)
                {
                    error.write_error_log(ex.Message + ex.StackTrace);
                    Debug.WriteLine(ex.Message + ex.StackTrace);

                }

            }



            db_all_video_lists = sql_class.sql_all_db(config_class.config_int_read("動画DBのソート"), config_class.config_int_read("動画DBのソートの順序"));
            if (config_class.config_int_read("起動時のリスト") == 1)
            {
                list_folder();
            }
            if (config_class.config_int_read("起動時のリスト") == 2)
            {
                list_db();

            }
            if (config_class.config_int_read("起動時のリスト") == 3)
            {
                list_abema();

            }

            if (config_class.config_int_read("起動時のリスト") == 5)
            {


                list_fast();

            }
            if (config_class.config_int_read("起動時のリスト") == 6)
            {


                list_rakuten();

            }
          
           
            if (config_class.config_int_read("起動時のリスト") == 9)
            {


                list_zhon();

            }
            if (config_class.config_bool_read("OverClockedReMixをリスト追加") == true)
            {

                Task.Run(() =>
                               OverClocked_remix_lists = TextListLoader.Load_no_Contains("OverClocked_remix.txt")



                            );
            }


            if (config_class.config_bool_read("起動時にepgのxmlを更新") == true)
            {

                var service = new Web_update();
      
                if (xml_update_check("animenosekai_epg.xml") == false)
                {
                    await service.epg_xml_get("https://animenosekai.github.io/japanterebi-xmltv/guide.xml", "animenosekai_epg.xml", true);
                }
                if (xml_update_check("jp_epg_26f0ce.xml") == false)
                {
                    await service.epg_xml_get("https://jp-epg-26f0ce.gitlab.io/guide.xml", "jp_epg_26f0ce.xml", true);
                }
                if (xml_update_check("karenda_epg.xml") == false)
                {
                    await service.epg_xml_get("https://raw.githubusercontent.com/karenda-jp/etc/refs/heads/main/guides.xml", "karenda_epg.xml", true);
                }
                if (xml_update_check("radiko_epg.xml") == false)
                {
                    var Radiko = new RadikoClient();
                    await Radiko.radiko_xml_write();


                }
            }

            abemaTV_cm_reaload_Timer.Interval = 10000;
            abemaTV_cm_reaload_Timer.Tick += abemaTV_cm_reaload_Tick;
            abemaTV_cm_reaload_Timer.Start();

           m3u8_title_replace_Timer.Interval = 10000;
            m3u8_title_replace_Timer.Tick += m3u8_title_replace_Tick;
            m3u8_title_replace_Timer.Start();

            Task.Run(() =>
                  xml_load()

            );
        
        }
        private void xml_load()
        {
            if (config_class.config_int_read("表示のEPG取得先") == 2)
            {
                if (System.IO.File.Exists("animenosekai_epg.xml"))
                {
                    doc_animenosekai_epg = XDocument.Load("animenosekai_epg.xml");

                }
            }
            if (config_class.config_int_read("表示のEPG取得先") == 3)
            {
                if (System.IO.File.Exists("karenda_epg.xml"))
                {
                    doc_karenda_epg = XDocument.Load("karenda_epg.xml");
                }

            }
            if (config_class.config_int_read("表示のEPG取得先") == 4)
            {
                if (System.IO.File.Exists("jp_epg_26f0ce.xml"))
                {
                    doc_jp_epg_26f0ce = XDocument.Load("jp_epg_26f0ce.xml");
                }

            }

            if (config_class.config_int_read("表示のEPG取得先") != 1)
            {
                if (System.IO.File.Exists("radiko_epg.xml"))
                {
                    doc_radiko_epg = XDocument.Load("radiko_epg.xml");
                }

            }

            
         

        }
        private static bool xml_update_check(String filePath)
        {


            if (File.Exists(filePath))
            {
                DateTime lastWrite = File.GetLastWriteTime(filePath);

                if ((DateTime.Now - lastWrite).TotalDays >= 1)
                {
                    Debug.WriteLine("ファイルは1日以上更新されていません");
                    return false;
                    // 1日以上前
                  
                }
                else
                {
                    return true;

                }
            }
            else
            {

                return false;
            }
            
        }
      
   
       
       
   
       

        
       


        private void UpdatePlaylistMenu(List<string> titleList, List<string> urlList)
        {

            capter_menuStrip.Items.Clear();

            ToolStripMenuItem playlistMenu = new ToolStripMenuItem("list");


            for (int i = 0; i < titleList.Count; i++)
            {
                try
                {
                    
                    var item = new ToolStripMenuItem(titleList[i]);


                    item.Tag = urlList[i];

                    item.Click += PlaylistItem_Click;

                    playlistMenu.DropDownItems.Add(item);
                }
                catch (System.Exception ex)
                {
                    error.write_error_log(ex.Message + ex.StackTrace);
                    Debug.WriteLine(ex.Message + ex.StackTrace);

                }




            }

            capter_menuStrip.Items.Add(playlistMenu);

            this.Controls.Add(capter_menuStrip);
        }
        private void PlaylistItem_Click(object sender, EventArgs e)
        {
            if (sender is ToolStripMenuItem item)
            {
                string url = item.Tag as string;

                if (!string.IsNullOrEmpty(url))
                {
                    Debug.WriteLine("クリックされたURL: " + url);
                    StartMpv(url);

                }
            }
        }

        public async void radiko_url_update()
        {
            try
            {
                if (System.IO.File.Exists("radiko.txt") == true)
                {
                    try { 
                    File.Delete(@"radiko.txt");
                }
                catch (System.Exception ex)
            {
              
                Debug.WriteLine(ex.Message + ex.StackTrace);

            }
        }
                    if (System.IO.File.Exists("radiko.txt") == false)
                {
                  
                    using (FileStream fs = File.Create(@"radiko.txt")) ;
                }


            }
            catch (System.Exception ex)
            {
                error.write_error_log(ex.Message + ex.StackTrace);
                Debug.WriteLine(ex.Message + ex.StackTrace);

            }

            var radiko = new RadikoClient();
            try
            {
                await radiko.Init();

           

                var stations = await radiko.GetStations();

                foreach (var s in stations)
                {
                   

                    File.AppendAllText("radiko.txt", "https://radiko.jp/#!/live/" + s.id + Environment.NewLine);



                }
            }
            catch (System.Exception ex)
            {
                error.write_error_log(ex.Message + ex.StackTrace);
                Debug.WriteLine(ex.Message + ex.StackTrace);

            }



        }
        public async void mov3_url_update()
        {
            var service = new Web_update();

            await service.update_mov3();
        }
        public async void abema_url_update()
        {
            var service = new Web_update();
            await service.AbemaUpdateFilesAsync();

        }
        public async void open_all_tv_ran()
        {
            var service = new epg();
            var xml_tuple = xml_get();
            XDocument tuple_doc = xml_tuple.doc;
          
               String xml_name = xml_tuple.xml_name;
           
            string html = "";
            if (System.Text.RegularExpressions.Regex.IsMatch(currentFilePath, @"https://radiko.jp/#\!/live/", System.Text.RegularExpressions.RegexOptions.IgnoreCase))
            {
                html = service.CreateRadikoAiiEpgHtml(
xml_name, tuple_doc);
            }
            else
            {

                html = service.CreateAllEpgHtml(
    xml_name, tuple_doc);
            }

            open_browser(html);


        }
        public async void open_radiko_all_tv_ran()
        {
            var service = new epg();
            var xml_tuple = xml_get();
            XDocument tuple_doc = xml_tuple.doc;

            String xml_name = xml_tuple.xml_name;
            string html = service.CreateRadikoAiiEpgHtml(
"radiko_epg.xml", tuple_doc);
          

            open_browser(html);


        }
        private (string xml_name, XDocument doc)  xml_get()
        {
            XDocument doc = new XDocument();
            String
               xml_name = "karenda_epg.xml";
            if (config_class.config_int_read("表示のEPG取得先") != 1)
            {

                if (System.Text.RegularExpressions.Regex.IsMatch(currentFilePath, @"https://radiko.jp/#\!/live/", System.Text.RegularExpressions.RegexOptions.IgnoreCase))
                {
                    xml_name = "radiko_epg.xml";
                    doc = doc_radiko_epg;

                    return (
               xml_name,
              doc
                  );
                }
            }

            if (config_class.config_int_read("表示のEPG取得先") == 2)
            {
          
                if (System.Text.RegularExpressions.Regex.IsMatch(currentFilePath, @"livetv.fastv.jp", System.Text.RegularExpressions.RegexOptions.IgnoreCase) ||
            System.Text.RegularExpressions.Regex.IsMatch(currentFilePath, @"amagi.tv.+?rakuten", RegexOptions.IgnoreCase) ||
            System.Text.RegularExpressions.Regex.IsMatch(currentFilePath, @"https://abema.tv/now-on-air/[\-_a-zA-Z0-9]+", RegexOptions.IgnoreCase) ||
            System.Text.RegularExpressions.Regex.IsMatch(currentFilePath, @"https://linear-abematv.akamaized.net/preview/channel/[\-_a-zA-Z0-9]+/playlist.m3u8", RegexOptions.IgnoreCase))
                {
                    xml_name = "karenda_epg.xml";
                    doc = doc_karenda_epg;
                }
                else
                {
                    xml_name = "animenosekai_epg.xml";
                    doc = doc_animenosekai_epg;

                }

            }
            if (config_class.config_int_read("表示のEPG取得先") ==3)
            {
                xml_name = "karenda_epg.xml";
                doc=doc_karenda_epg;
            }
                if (config_class.config_int_read("表示のEPG取得先") == 4)
            {
                xml_name = "jp_epg_26f0ce.xml";
                doc = doc_jp_epg_26f0ce;
            }

       

            return (
       xml_name,
      doc
          );

         
        }
        public async void open_white_list_tv_ran(HashSet<string> whitelist,String name,String xml_path)
        {
            var service = new epg();
            String xml_name = "";
            var xml_tuple= xml_get();
            XDocument tuple_doc = xml_tuple.doc;
            if (!string.IsNullOrEmpty(xml_path))
            {
                xml_name = xml_path;
            }
            else
            {
                xml_name = xml_tuple.xml_name;
            }
            string 
                html = service.CreateAllEpgHtml_whitelist(
    xml_name, whitelist , name, tuple_doc);
          

            open_browser(html);


        }
        public async void open_now_tv_ran()
        {
            var service = new epg();
           
            string html = "";
        
            var xml_tuple = xml_get();
            XDocument tuple_doc = xml_tuple.doc;
            String xml_name = xml_tuple.xml_name;
            if (System.Text.RegularExpressions.Regex.IsMatch(currentFilePath, @"https://radiko.jp/#\!/live/", System.Text.RegularExpressions.RegexOptions.IgnoreCase))
            {
                html = service.CreateNowRadikoHtml(
xml_name, tuple_doc);
            }
            else
            {
                html = service.CreateNowEpgHtml(
  xml_name, tuple_doc);
            }

            open_browser(html);

        }
        public async void open_single_tv_ran()
        {
            
            var service = new epg();
          
            var xml_tuple = xml_get();
            XDocument tuple_doc = xml_tuple.doc;

            String xml_name = xml_tuple.xml_name;


            String c_id = "";
            if (channel_class.channel_id != null)
            {
                c_id = channel_class.channel_id;
            }
             string html = "";
            if (System.Text.RegularExpressions.Regex.IsMatch(currentFilePath, @"https://radiko.jp/#\!/live/", System.Text.RegularExpressions.RegexOptions.IgnoreCase))
            {
                
                html = service.Create_single_RadikoHtml(
xml_name,
c_id, tuple_doc);
            }
            else
            {
                html = service.Create_single_EpgHtml(
  xml_name,
 c_id, tuple_doc);
            }

            open_browser(html);



}

        private void open_browser(String html)
        {
            if (!string.IsNullOrEmpty(html))
            {
                try
                {

                    File.WriteAllText(@"epg.html", html);
                    if (System.IO.File.Exists("epg.html"))
                    {

                        Process.Start(new ProcessStartInfo
                        {
                            FileName = "epg.html",
                            UseShellExecute = true
                        });
                    }
                }
                catch (System.Exception ex)
                {
                    Debug.WriteLine(ex.Message + ex.StackTrace);

                }
            }

        }
   
     
        public async void animenosekai_xml_get()
        {
            var service = new Web_update();
            await service.epg_xml_get("https://animenosekai.github.io/japanterebi-xmltv/guide.xml", "animenosekai_epg.xml", true);
            Task.Run(() =>
                  xml_load()

            );
        }
        public async void radiko_xml_get()
        {
            var service = new RadikoClient();
            await service.radiko_xml_write();
            Task.Run(() =>
                  xml_load()

            );
        }
        public async void karenda_xml_get()
        {
            var service = new Web_update();
            await service.epg_xml_get("https://raw.githubusercontent.com/karenda-jp/etc/refs/heads/main/guides.xml", "karenda_epg.xml", true);
            Task.Run(() =>
                   xml_load()

             );
        }
        //jp_epg_26f0ce
        public async void jp_epg_26f0ce_xml_get()
        {
            var service = new Web_update();
            await service.epg_xml_get("https://jp-epg-26f0ce.gitlab.io/guide.xml", "jp_epg_26f0ce.xml", true);
            Task.Run(() =>
                  xml_load()

            );
        }
        public async void all_xml_get()
        {
            var service = new Web_update();
            await service.epg_xml_get("https://animenosekai.github.io/japanterebi-xmltv/guide.xml", "animenosekai_epg.xml", true);

           
                await service.epg_xml_get("https://jp-epg-26f0ce.gitlab.io/guide.xml", "jp_epg_26f0ce.xml", true);
          
            await service.epg_xml_get("https://raw.githubusercontent.com/karenda-jp/etc/refs/heads/main/guides.xml", "karenda_epg.xml", true);
            var Radiko = new RadikoClient();
            await Radiko.radiko_xml_write();
            Task.Run(() =>
                  xml_load()

            );
        }
        public async void ytdlp_update()
        {
            var service = new Web_update();
            String ytdlp_path = config_class.config_text_read("yt-dlpのパス");
           
                 service.YtDlpUpdate(ytdlp_path);
            

        }
        public void PlayerPanel_SIngleClick(object? sender, EventArgs e)
        {
            if (config_class.config_bool_read("動画ウインドウをシングルクリックで動作を有効") == true)
            {
                if (config_class.config_int_read("動画ウインドウのシングルクリックの動作") == 1)
                {
                    next_movie();
                }
                if (config_class.config_int_read("動画ウインドウのシングルクリックの動作") == 2)
                {
                    ToggleFullScreen();
                }
                if (config_class.config_int_read("動画ウインドウのシングルクリックの動作") == 3)
                {
                    pause_func();
                }
                if (config_class.config_int_read("動画ウインドウのシングルクリックの動作") == 4)
                {
                    mute_func();
                }
            }
        }
        private void Form1_DragEnter(object sender, DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop) ||
        e.Data.GetDataPresent(DataFormats.Text) ||
        e.Data.GetDataPresent("UniformResourceLocator"))
            {
                e.Effect = DragDropEffects.Copy;
            }
            else
            {
                e.Effect = DragDropEffects.None;
            }
        }
        private async void Form1_DragDrop(System.Object sender, System.Windows.Forms.DragEventArgs e)
        {
            if (e.Data.GetDataPresent(DataFormats.FileDrop))
            {
                string[] paths = (string[])e.Data.GetData(DataFormats.FileDrop);
                if (paths.Length > 0 && System.IO.File.Exists(paths[0]))
                {
                    currentFilePath = paths[0];
                    
                    if (System.IO.File.Exists(paths[0]))
                    {

                        if (System.Text.RegularExpressions.Regex.IsMatch(paths[0], config_class.config_text_read("動画取得の拡張子の正規表現"), System.Text.RegularExpressions.RegexOptions.IgnoreCase))
                        {
                            StartMpv(paths[0]);
                        }
                      
                    }

                    await Task.Run(() =>
                    {
                        foreach (var get_path in paths)
                        {
                            if (folder_movie_lists.Contains(get_path) == false)
                            {
                                if (System.IO.File.Exists(get_path))
                                {
                                    if (System.Text.RegularExpressions.Regex.IsMatch(paths[0], config_class.config_text_read("動画取得の拡張子の正規表現"), System.Text.RegularExpressions.RegexOptions.IgnoreCase))
                                    {
                                        folder_movie_lists.Add(get_path);
                                    }
                                }
                            }




                        }

                    });
                    start_list_update(paths[0]);

                }


            }




            // URL（テキスト）が来た場合
            if (e.Data.GetDataPresent(DataFormats.Text))
            {
                string text = e.Data.GetData(DataFormats.Text).ToString();




                if (System.Uri.IsWellFormedUriString(text, UriKind.Absolute))
                {
                    StartMpv(text);
                }
            }



        }
        public void argument_window_open()
        {
            argument_window ins = new argument_window(_myplayer.Mpv_argument);
            ins.Show();


        }
        public void yoyaku_window_open()
        {
            ReservationForm ins = new ReservationForm( doc_animenosekai_epg, doc_karenda_epg,
 doc_jp_epg_26f0ce,  doc_radiko_epg);
            ins.Show();


        }
        public void setting_open()
        {

            SettingsForm ins = new SettingsForm();

            ins.Show();
            ins.FormClosed += (sender, e) =>
            {
                Task.Run(() =>
                  xml_load()

            );
                // ウインドウが閉じた後に実行したい処理
               
            };
            

        }
        public void listview_open()
        {
            VideoListView ins = new VideoListView(this);

            ins.Show();

        }


        public void audio_window_open()
        {
            EqualizerForm ins = new EqualizerForm(_myplayer);

            ins.Show();

        }

        public void d_d_window_open()
        {
            DragDropForm ins = new DragDropForm();
            ins.Show();

        }


        public void videoinfo_window_open()
        {
            InfoForm ins = new InfoForm(_videoState);
            ins.Show();

        }
        public void reboot()
        {
            StopMpv();
            try
            {
                Process[] ps = Process.GetProcessesByName("mpv");
                foreach (Process item in ps)
                {

                    item.Kill();
                    item.Close();
                    item.Dispose();
                }
            }
            catch (System.Exception ex)
            {
                Debug.WriteLine(ex.Message + ex.StackTrace);

            }
            if (System.Text.RegularExpressions.Regex.IsMatch(currentFilePath, "https?:", System.Text.RegularExpressions.RegexOptions.IgnoreCase))
            {


                if (System.Text.RegularExpressions.Regex.IsMatch(currentFilePath, @"https://linear-abematv.akamaized.net/preview/channel/[A-Za-z0-9\-_]+/playlist.m3u8", System.Text.RegularExpressions.RegexOptions.IgnoreCase))
                {
                    try
                    {
                        Process[] ps = Process.GetProcessesByName("streamlink");
                        foreach (Process item in ps)
                        {

                            item.Kill();
                            item.Close();
                            item.Dispose();
                        }
                    }
                    catch (System.Exception ex)
                    {
                        Debug.WriteLine(ex.Message + ex.StackTrace);

                    }
                }

                else
                {
                    try
                    {
                        Process[] ps = Process.GetProcessesByName("yt-dlp");
                        foreach (Process item in ps)
                        {

                            item.Kill();
                            item.Close();
                            item.Dispose();
                        }
                    }
                    catch (System.Exception ex)
                    {
                        Debug.WriteLine(ex.Message + ex.StackTrace);

                    }

                }
            }

            play_func();
        }

        public void url_paste_func()
        {
            if (Clipboard.ContainsText())
            {
                string text = Clipboard.GetText();
                if (System.Text.RegularExpressions.Regex.IsMatch(text, "https?://.*", System.Text.RegularExpressions.RegexOptions.IgnoreCase))
                {
                    StartMpv(text);
                }
                else
                {
                    return;
                }




            }
        }
        public void close_func()
        {
            this.Close();
        }
        private void close(object sender, FormClosingEventArgs e)
        {
         
            config_class.save_config_file("url", currentFilePath);



            StopMpv();
            try
            {
                Process[] ps = Process.GetProcessesByName("mpv");
                foreach (Process item in ps)
                {

                    item.Kill();
                    item.Close();
                    item.Dispose();
                }
            }
            catch (System.Exception ex)
            {
                Debug.WriteLine(ex.Message + ex.StackTrace);

            }



        }

        public void Speed_change(Double value)
        {
            _myplayer.ChangeSpeed(value);
        }
        public void Speed_change_no_osd(Double value)
        {
            _myplayer.ChangeSpeed_no_osd(value);
        }
        public void SpeedUp()
        {

            string val = config_class.config_text_read("SPEEDアップ数");

            if (!double.TryParse(val, NumberStyles.Float, CultureInfo.InvariantCulture, out double up_su))
            {
                up_su = 0.1; // デフォルト
            }

            // 減算
            _currentSpeed = _currentSpeed + up_su;


            if (_currentSpeed > 10)
                _currentSpeed = 10.0;

            _currentSpeed = Math.Round(_currentSpeed, 1);
            Speed_change(_currentSpeed);

        }

        public void SpeedDown()
        {
            string val = config_class.config_text_read("SPEEDアップ数");

            if (!double.TryParse(val, NumberStyles.Float, CultureInfo.InvariantCulture, out double down))
            {
                down = 0.1; // デフォルト
            }

            // 減算
            _currentSpeed = _currentSpeed - down;

            // 下限ガード（重要）
            if (_currentSpeed < 0.1)
                _currentSpeed = 0.1;
            _currentSpeed = Math.Round(_currentSpeed, 1);
            Speed_change(_currentSpeed);
        }




        public void bt_cap_prev()
        {

            cap_position = cap_position - 1;
            if (cap_position <= 0)
            {
                cap_position = cap_size;
            }
            _myplayer.ChangeChapter(cap_position);



        }



        public void bt_cap_next()
        {

            cap_position = cap_position + 1;
            if (cap_position > cap_size)
            {
                cap_position = 0;

            }

            _myplayer.ChangeChapter(cap_position);



        }


        public void NextSeek()
        {

            if (_duration <= 0) return;
            string val = config_class.config_text_read("シークする時の飛ばすフレーム数");

            if (!double.TryParse(val, NumberStyles.Float, CultureInfo.InvariantCulture, out double seek_flame))
            {
                seek_flame = 10.0; // デフォルト
            }
           
            _myplayer.NextSeek(seek_flame);




        }

        public void PrevSeek()
        {
            if (_duration <= 0) return;
            string val = config_class.config_text_read("シークする時の飛ばすフレーム数");

            if (!double.TryParse(val, NumberStyles.Float, CultureInfo.InvariantCulture, out double seek_flame))
            {
                seek_flame = 10.0; // デフォルト
            }

            _myplayer.PrevSeek(seek_flame);


        }
        public void play_func()
        {
            StartMpv(currentFilePath);


        }
       
        public void pause_func()
        {
            _myplayer.TogglePause();

        }
        private async void folder_get(String folder_path)
        {
            folder_movie_lists = new List<String>();
            if (System.IO.Directory.Exists(folder_path) == false)
            {
                return;

            }
            try
            {



                string[] files = System.IO.Directory.GetFiles(
       folder_path, "*", System.IO.SearchOption.TopDirectoryOnly);

                foreach (string movie_path in files)
                {



                    if (System.Text.RegularExpressions.Regex.IsMatch(movie_path, config_class.config_text_read("動画取得の拡張子の正規表現"), System.Text.RegularExpressions.RegexOptions.IgnoreCase))
                    {
                        if (System.IO.File.Exists(movie_path) == true)
                        {
                            folder_movie_lists.Add(movie_path);
                        }
                    }


                }

            }
            catch (System.Exception ex)
            {
                error.write_error_log(ex.Message + ex.StackTrace);
                Debug.WriteLine(ex.Message + ex.StackTrace);

            }






        }
        private async void folder_get_movie(String video_path)
        {
            

            if (System.IO.File.Exists(video_path) == false)
            {
                return;

            }
            String dir_path = "";
            try
            {
                dir_path = System.IO.Path.GetDirectoryName(video_path);
             
            
          




            var files2 = new DirectoryInfo(dir_path)
             .GetFiles("*", System.IO.SearchOption.TopDirectoryOnly)
             .Where(f => Regex.IsMatch(f.FullName,
                 config_class.config_text_read("動画取得の拡張子の正規表現"),
                 RegexOptions.IgnoreCase));
              
                int sortType = config_class.config_int_read("フォルダ動画のソート");
            
                IEnumerable<FileInfo> sorted=files2;

            switch (sortType)
            {
                case 1: // 更新日時
                    if (config_class.config_int_read("フォルダ動画のソートの順序") == 1)
                    {
                      
                        sorted = files2.OrderByDescending(f => f.LastWriteTime);

                    }
                    if (config_class.config_int_read("フォルダ動画のソートの順序") == 2)
                        {
                         
                            sorted = files2.OrderBy(f => f.LastWriteTime);

                    }
                    break;

                case 2: // 作成順
                    if (config_class.config_int_read("フォルダ動画のソートの順序") == 1)
                    {
                        sorted = files2.OrderByDescending(f => f.CreationTime);

                    }
                    if (config_class.config_int_read("フォルダ動画のソートの順序") == 2)
                    {
                        sorted = files2.OrderBy(f => f.CreationTime);

                    }


                    break;
                case 3: // 名前順
                    if (config_class.config_int_read("フォルダ動画のソートの順序") == 1)
                    {
                        sorted = files2.OrderByDescending(f => f.Name);

                    }
                    if (config_class.config_int_read("フォルダ動画のソートの順序") == 2)
                    {
                        sorted = files2.OrderBy(f => f.Name);

                    }
                    break;
                case 4: // サイズ順 
                    if (config_class.config_int_read("フォルダ動画のソートの順序") == 1)
                    {
                        sorted = files2.OrderByDescending(f => f.Length);

                    }
                    if (config_class.config_int_read("フォルダ動画のソートの順序") == 2)
                    {
                        sorted = files2.OrderBy(f => f.Length);

                    }
                    break;


               
            }
          
            folder_movie_lists = sorted.Select(f => f.FullName).ToList();
            }
            catch (System.Exception ex)
            {
                error.write_error_log(ex.Message + ex.StackTrace);
                Debug.WriteLine(ex.Message + ex.StackTrace);

            }


        }
        private void UpdateVRView()
        {
            _myplayer.Video.vr360_mode_command(yaw_360,  fov_360, pitch_360, roll_360);
        }
        public void list_change(String name, List<String> list)
        {
            main_video_count = 0;
            main_video_lists = list;
            BeginInvoke(() =>
            {
                lbl_list_name.Text = name;
                if (main_video_lists != null)
                {
                    ListSlider.Maximum = main_video_lists.Count();
                    lbl_Listsize.Text = main_video_count.ToString() + "/" + main_video_lists.Count().ToString();
                }
            });

        }
        public void list_abema()
        {
            list_change("Abema", abema_stream_lists);

        }
        public void list_OverClocked_remix()
        {
        
            list_change("Ocremix", OverClocked_remix_lists);

        }
        public void list_seach()
        {
            list_change("検索", search_lists);


        }
        public void list_folder()
        {
            list_change("フォルダ", folder_movie_lists);


        }
        


        public void list_youtube_playlist()
        {
            list_change("playlist", youtube_play_lists_url);


        }
        public void list_fast()
        {
            list_change("fast", fast_lists);


        }
       
      
        public void list_akari()
        {
            list_change("akari", akariko_lists);


        }
        public void list_mov3()
        {
            list_change("mov3", mov3_lists);


        }
      
        public void list_zhon()
        {
            list_change("zhon", zhon_lists);


        }
        public void open_video_window()
        {


            video_window ins = new video_window(_myplayer.Controller);

            ins.Show();
        }
        public void open_audio_window()
        {
            EqualizerForm ins = new EqualizerForm(_myplayer);

            ins.Show();
        }
        private void OnVideoEnded()
        {

            if (config_class.config_int_read("終了後の動作") == 1)
            {
                next_movie();
                StartMpv(currentFilePath);

            }
            if (config_class.config_int_read("終了後の動作") == 2)
            {
                StartMpv(currentFilePath);
            }

            if (config_class.config_int_read("終了後の動作") == 3)
            {
                randam_movie();
                StartMpv(currentFilePath);
            }
            if (config_class.config_int_read("終了後の動作") == 4)
            {
                StopMpv();
            }


        }
        public void home_movie()
        {

            main_video_count = 0;
            String url = "";

            try
            {
                url = main_video_lists[main_video_count];
            }

            catch (System.Exception ex)
            {
                error.write_error_log(ex.Message + ex.StackTrace);

                Debug.WriteLine(ex.Message + ex.StackTrace);
             
            }

            url_replace(url);
            lbl_Listsize.Text = main_video_count.ToString() + "/" + main_video_lists.Count().ToString();
            if (ListSlider.Maximum >= main_video_count)
            {
                ListSlider.Value = main_video_count;
            }
        }
        public void half_movie()
        {

            Double count_d = main_video_lists.Count/2;
            main_video_count = (int)Math.Round(count_d);
            String url = "";

            try
            {
                url = main_video_lists[main_video_count];
            }

            catch (System.Exception ex)
            {
                error.write_error_log(ex.Message + ex.StackTrace);

                Debug.WriteLine(ex.Message + ex.StackTrace);
                
            }

            url_replace(url);
            lbl_Listsize.Text = main_video_count.ToString() + "/" + main_video_lists.Count().ToString();
            if (ListSlider.Maximum >= main_video_count)
            {
                ListSlider.Value = main_video_count;
            }
        }

        public void randam_movie()
        {

            int ran_saidai = main_video_lists.Count;
            Random rnd = new Random();    // Randomオブジェクトの作成
            main_video_count = rnd.Next(0, ran_saidai);  //1以上10未満の値がランダムに出deo_count = 0;

            String url = "";

            try
            {
                url = main_video_lists[main_video_count];
            }

            catch (System.Exception ex)
            {
                error.write_error_log(ex.Message + ex.StackTrace);

                Debug.WriteLine(ex.Message + ex.StackTrace);
                
            }

            url_replace(url);
            lbl_Listsize.Text = main_video_count.ToString() + "/" + main_video_lists.Count().ToString();
            if (ListSlider.Maximum >= main_video_count)
            {
                ListSlider.Value = main_video_count;
            }
        }
        public void next_movie()
        {

            if (main_video_lists.Count <= 1)
            {

                return;
            }

            main_video_count = main_video_count + 1;



            if (main_video_lists.Count < main_video_count)
            {
                main_video_count = 0;
            }
            String url = "";

            try
            {
                url = main_video_lists[main_video_count];
                currentFilePath = url;
            }

            catch (System.Exception ex)
            {
                error.write_error_log(ex.Message + ex.StackTrace);

                Debug.WriteLine(ex.Message + ex.StackTrace);
                
            }
            if (System.Text.RegularExpressions.Regex.IsMatch(url, config_class.config_text_read("streamlinkで取得するURLの正規表現"), System.Text.RegularExpressions.RegexOptions.IgnoreCase))
            {
                return;
            }
            else
            {

                url_replace(url);
            }

            lbl_Listsize.Text = main_video_count.ToString() + "/" + main_video_lists.Count().ToString();
            if (ListSlider.Maximum >= main_video_count)
            {
                ListSlider.Value = main_video_count;
            }
        }
        public void prev_movie()
        {
            if (main_video_lists.Count == 1)
            {

                return;
            }
            main_video_count = main_video_count - 1;
            if (main_video_count < 0)
            {
                main_video_count = main_video_lists.Count;
            }
            String url = "";

            try
            {
                url = main_video_lists[main_video_count];
                currentFilePath = url;
            }

            catch (System.Exception ex)
            {
                error.write_error_log(ex.Message + ex.StackTrace);

                Debug.WriteLine(ex.Message + ex.StackTrace);
                
            }

            if (System.Text.RegularExpressions.Regex.IsMatch(url, config_class.config_text_read("streamlinkで取得するURLの正規表現"), System.Text.RegularExpressions.RegexOptions.IgnoreCase))
            {
                return;
            }
            else
            {

                url_replace(url);
            }
            lbl_Listsize.Text = main_video_count.ToString() + "/" + main_video_lists.Count().ToString();
            if (ListSlider.Maximum >= main_video_count)
            {
                ListSlider.Value = main_video_count;
            }
        }
        public void delete()
        {
            if (string.IsNullOrEmpty(currentFilePath))
            {
                return;
            }

            
            if (System.IO.File.Exists(currentFilePath) == false)
            {
                return;
            }
          


            if (config_class.config_bool_read("削除機能を有効") == true)
            {
                if (config_class.config_bool_read("削除で確認する") == true)
                {     //メッセージボックスを表示する
                    DialogResult result = MessageBox.Show(currentFilePath + "を削除しますか？",
                "質問",
                MessageBoxButtons.YesNoCancel,
                MessageBoxIcon.Exclamation,
                MessageBoxDefaultButton.Button2);

                    //何が選択されたか調べる
                    if (result == DialogResult.Yes)
                    {
                        StopMpv();
                        try
                        {
                            Microsoft.VisualBasic.FileIO.FileSystem.DeleteFile(
                        currentFilePath,
                        UIOption.AllDialogs,
                        RecycleOption.SendToRecycleBin,
                        UICancelOption.DoNothing
                        );
                            this.Text = currentFilePath + "を削除しました。";
                            next_movie();
                        }
                        catch (System.Exception ex)
                        {
                            error.write_error_log(ex.Message + ex.StackTrace);

                            Debug.WriteLine(ex.Message);

                        }
                    }
                    else if (result == DialogResult.No)
                    {
                        //「いいえ」が選択された時
                        this.Text = currentFilePath + "削除をキャンセルしました";
                    }
                    else if (result == DialogResult.Cancel)
                    {
                        //「キャンセル」が選択された時
                        this.Text = currentFilePath + "削除をキャンセルしました";
                    }
                    return;
                }
                else
                {

                    StopMpv();
                    try
                    {
                        Microsoft.VisualBasic.FileIO.FileSystem.DeleteFile(
                             currentFilePath,
                             UIOption.AllDialogs,
                             RecycleOption.SendToRecycleBin,
                             UICancelOption.DoNothing
                             );
                        this.Text = currentFilePath + "を削除しました。";
                        next_movie();
                    }
                    catch (System.Exception ex)
                    {
                        error.write_error_log(ex.Message + ex.StackTrace);

                        Debug.WriteLine(ex.Message);

                    }
                }
            }
           
               



           



        }
        private void Audio_Click(object sender, EventArgs e)
        {
            if (sender is ToolStripMenuItem item && item.Tag is int id)
            {
                _myplayer.Set_mutli_audio(id);

            }
        }
        private void Sub_Click(object sender, EventArgs e)
        {
            if (sender is ToolStripMenuItem item && item.Tag is int id)
            {
                if (id == -1)
                {

                    _myplayer.Set_mutli_sub_no();

                }
                else
                {

                    _myplayer.Set_mutli_sub(id);

                }
            }
        }
        private void UpdateTrackMenu(List<MpvTrack> tracks)
        {

            capter_menuStrip.Items.Remove(menuAudio);
            capter_menuStrip.Items.Remove(menuSub);


            menuAudio = new ToolStripMenuItem("音声");
            menuSub = new ToolStripMenuItem("字幕");

            var audioTracks = tracks.Where(t => t.type == "audio").ToList();
            var subTracks = tracks.Where(t => t.type == "sub").ToList();

            // --- 音声 ---
            menuAudio.DropDownItems.Clear();

            foreach (var t in audioTracks)
            {
                var item = new ToolStripMenuItem(t.DisplayName);
                item.Tag = t.id;
                item.Click += Audio_Click;

                menuAudio.DropDownItems.Add(item);
            }

            // --- 字幕 ---
            menuSub.DropDownItems.Clear();

            // OFF
            var offItem = new ToolStripMenuItem("OFF");
            offItem.Tag = -1;
            offItem.Click += Sub_Click;
            menuSub.DropDownItems.Add(offItem);

            foreach (var t in subTracks)
            {
                var item = new ToolStripMenuItem(t.DisplayName);
                item.Tag = t.id;
                item.Click += Sub_Click;

                menuSub.DropDownItems.Add(item);
            }


            capter_menuStrip.Items.Add(menuAudio);
            capter_menuStrip.Items.Add(menuSub);




            this.Controls.Add(capter_menuStrip);
        }

        public void FrameStep()
        {

            _myplayer.FrameStep();
        }
        public void FrameBackStep()
        {

            _myplayer.FrameBackStep();
        }
        private void ZoomUp()
        {
            _myplayer.ZoomUp();
        }

        private void ZoomDown()
        {
            _myplayer.ZoomDown();
        }
        private void ZoomNormal()
        {
            _myplayer.ZoomNormal();
        }
        private void pan_x_plus()
        {
            _myplayer.pan_x_plus();
        }
        private void pan_x_minus()
        {
            _myplayer.pan_x_minus();
        }
        private void pan_y_plus()
        {
            _myplayer.pan_y_plus();
        }
        private void pan_y_minus()
        {
            _myplayer.pan_y_minus();
        }

        public void video_crop(String crop)
        {
            _myplayer.Video.video_crop(crop);
        }
        private void sub_srt_zoom()
        {

            // 減算
            _subsize = _subsize + 0.05;

            if (_subsize > 5)
                _subsize = 8.0;


            _myplayer.sub_srt_zoom(_subsize);
        }
        public void PositionSlider_MouseDown(object sender, MouseEventArgs e)
        {

            _pos_slidr_isDragging = true;

            //// ★ クリック位置で即ジャンプ（WPFと同じ挙動）
            SetSliderValueFromMouse(e.X);
        }
        private void sub_srt_zoom_out()
        {
            // 減算
            _subsize = _subsize - 0.05;

            // 下限ガード（重要）
            if (_subsize < 0.3)
                _subsize = 0.3;


            _myplayer.sub_srt_zoom(_subsize);
        }
        private void sub_pos_y_plus()
        {

            // 減算
            _sub_pos_y = _sub_pos_y + 1;

            if (_sub_pos_y > 100)
                _sub_pos_y = 100;


            _myplayer.sub_pos_y(_sub_pos_y);

        }
        private void sub_pos_y_minus()
        {

            // 減算
            _sub_pos_y = _sub_pos_y - 1;

            if (_sub_pos_y < 0)
                _sub_pos_y = 0;


            _myplayer.sub_pos_y(_sub_pos_y);

        }




        private void Form1_KeyDown(object sender, KeyEventArgs e)

        {
           
            if (_isVr360Mode)
            {
               

                    if (e.Control)
                    {

                        switch (e.KeyCode)
                        {
                            case Keys.NumPad8: // 上
                                pitch_360 += step_360;
                                vr360Dirty = true;
                                break;
                            case Keys.Z:
                                // 正面
                                yaw_360 = 0;
                                pitch_360 = 0;
                                vr360Dirty = true;
                                break;

                            case Keys.X:
                                // 右
                                yaw_360 = 90;
                                vr360Dirty = true;
                                break;

                            case Keys.C:
                                // 後ろ
                                yaw_360 = 180;
                                vr360Dirty = true;
                                break;
                            case Keys.V:
                                // 左
                                yaw_360 = -90;
                                vr360Dirty = true;
                                break;
                            case Keys.NumPad2: // 下

                                pitch_360 -= step_360;
                                vr360Dirty = true;
                                break;

                            case Keys.NumPad4: // 左
                                yaw_360 -= step_360;
                                vr360Dirty = true;
                                break;

                            case Keys.NumPad6: // 右
                                yaw_360 += step_360;
                                vr360Dirty = true;
                                break;
                            case Keys.Add:
                                fov_360 -= 5; // ズームイン
                                vr360Dirty = true;
                                break;
                            case Keys.Subtract:
                                fov_360 += 5; // ズームアウト
                                vr360Dirty = true;
                                break;
                            case Keys.NumPad7: // 傾ける
                                roll_360 += 5;
                                vr360Dirty = true;
                                break;

                            case Keys.NumPad9: // 傾ける
                                roll_360 -= 5;
                                vr360Dirty = true;

                                break;
                        default:
                            break;
                    }
                    fov_360 = Math.Max(30, Math.Min(120, fov_360));

                    // 上下制限（ひっくり返り防止）
                    pitch_360 = Math.Max(-90, Math.Min(90, pitch_360));
                    roll_360 = Math.Max(-180, Math.Min(180, roll_360));


                }
                if (e.Alt)
                    {
                        switch (e.KeyCode)
                        {
                            case Keys.NumPad8:
                                // 上
                                pitch_360 = -90;
                                vr360Dirty = true;

                                break;

                            case Keys.NumPad2:
                                // 下
                                pitch_360 = 90;
                                vr360Dirty = true;
                                break;

                            case Keys.NumPad4:
                                // 左
                                yaw_360 = -90;

                                vr360Dirty = true;
                                break;

                            case Keys.NumPad6:
                                // 右
                                yaw_360 = 90;
                                vr360Dirty = true;
                                break;
                            case Keys.NumPad7:
                                // 後ろ
                                yaw_360 = 180;
                                vr360Dirty = true;
                                break;
                            case Keys.NumPad9:
                                // 正面
                                yaw_360 = 0;
                                pitch_360 = 0;
                                vr360Dirty = true;
                                break;
                        default:
                            break;
                    }
                    fov_360 = Math.Max(30, Math.Min(120, fov_360));

                    // 上下制限（ひっくり返り防止）
                    pitch_360 = Math.Max(-90, Math.Min(90, pitch_360));
                    roll_360 = Math.Max(-180, Math.Min(180, roll_360));


                }


            }
            if (!_isVr360Mode)
            {
                if (e.Control && e.KeyCode == Keys.Add)
                {
                    sub_srt_zoom();

                }


                if (e.Control && e.KeyCode == Keys.Subtract)
                {
                    sub_srt_zoom_out();

                }

                if (e.Control && e.KeyCode == Keys.NumPad8)
                {
                    sub_pos_y_minus();

                }
                if (e.Control && e.KeyCode == Keys.NumPad2)
                {
                    sub_pos_y_plus();

                }
            }
            if (e.KeyData == Keys.Delete)
            {
                delete();
            }
            if (e.KeyData == Keys.Subtract)
            {
                ZoomDown();
            }
            if (e.KeyData == Keys.NumPad6)
            {
                pan_x_plus();
            }
            if (e.KeyData == Keys.NumPad4)
            {
                pan_x_minus();
            }
            if (e.KeyData == Keys.NumPad8)
            {
                pan_y_minus();
            }
            if (e.KeyData == Keys.NumPad2)
            {
                pan_y_plus();
            }
            if (e.KeyData == Keys.NumPad5)
            {
                ZoomNormal();
            }
            if (e.KeyData == Keys.Add)
            {
                ZoomUp();
            }
            if (e.KeyData == Keys.Q)
            {
                ZoomNormal();
            }


            if (e.KeyData == Keys.Oemcomma)
            {
                if (!_frameBackStepTimer.Enabled)
                {

                    FrameBackStep(); // 1回目は即実行
                    _frameBackStepTimer.Start();
                }
            }
            if (e.KeyData == Keys.OemPeriod)
            {
                if (!_frameStepTimer.Enabled)
                {

                    FrameStep(); // 1回目は即実行
                    _frameStepTimer.Start();
                }
            }
            //ランダムな動画
            if (e.KeyData == Keys.R)
            {
                randam_movie();
            }

            if (e.KeyData == Keys.F)
            {
                ToggleFullScreen();


            }
            if (e.KeyData == Keys.E)
            {
                reload();


            }
            if (e.KeyData == Keys.I)
            {
                reboot();


            }
            if (e.KeyData == Keys.S)
            {

                ss_func();

            }
            if (e.KeyData == Keys.D)
            {
                record_url();


            }
            //SPEED UP
            if (e.KeyData == Keys.K)
            {
                SpeedUp();
            }
            if (e.KeyData == Keys.J)
            {
                SpeedDown();


            }



            if (e.KeyData == Keys.L)
            {
                Speed_change(1.0);


            }

            if (e.KeyData == Keys.T)
            {
                audio_delay_down();


            }
            if (e.KeyData == Keys.Y)
            {
                audio_delay_up();


            }
         
            if (e.KeyData == Keys.Right)
            {
          
                NextSeek();
                return;

            }
            if (e.KeyData == Keys.Left)
            {

                PrevSeek();
                return;

            }
            if (e.KeyData == Keys.G)
            {
                list_type = list_type + 1;
                if (list_type >= 8)
                {
                    list_type = 0;

                }
                list_key();
                return;

            }
            if (e.KeyData == Keys.H)
            {
                list_type = list_type - 1;
                if (list_type < 0)
                {
                    list_type = 7;

                }
                list_key();


                return;

            }
            if (e.KeyData == Keys.PageUp)
            {

                next_movie();
                return;

            }
            if (e.KeyData == Keys.Home)
            {

                home_movie();
                return;

            }
            if (e.KeyData == Keys.End)
            {

                half_movie();
                return;

            }
            if (e.KeyData == Keys.PageDown)
            {

                prev_movie();
                return;

            }
            if (e.KeyData == Keys.A)
            {

                a_marker_creat();
                return;

            }
            if (e.KeyData == Keys.B)
            {

                b_marker_creat();
                return;

            }
            if (e.KeyData == Keys.N)
            {

                ab_loop_start();
                return;

            }
            if (e.KeyData == Keys.O)
            {
                sub_delay_down();
                return;

            }

            if (e.KeyData == Keys.P)
            {
                sub_delay_up();

                return;

            }
        }
        private void sub_delay_up()
        {
            _myplayer.sub_delay_up();
        }
        private void sub_delay_down()
        {
            _myplayer.sub_delay_down();
        }
        private void Form_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.U)
            {
                _frameStepTimer.Stop();
            }
        }
        private void list_key()
        {
            if (list_type == 0)
            {
                list_folder();
            }
            if (list_type == 1)
            {
                list_db();
            }
            if (list_type == 2)
            {
                list_abema();
            }
            if (list_type == 3)
            {
                list_rakuten();
            }
            if (list_type == 4)
            {
                list_fast();
            }
         
         
            if (list_type == 5)
            {
                list_zhon();
            }
            if (list_type == 6)
            {
                list_akari();
            }
            if (list_type ==7)
            {
                list_mov3();
            }
        }


        public void PlayerPanel_MouseMove(object sender, MouseEventArgs e)
        {
            if (!_isFullScreen) return;

            Point clientCursorPos = this.PointToClient(Cursor.Position);

            BottomControlPanel.Top = this.ClientSize.Height - BottomControlPanel.Height;

            // 判定
            if (clientCursorPos.Y >= BottomControlPanel.Top - 10)
            {
                if (!BottomControlPanel.Visible)
                {
                    BottomControlPanel.Visible = true;
                    BottomControlPanel.BringToFront();
                }
            }
            else
            {
                if (BottomControlPanel.Visible)
                {
                    BottomControlPanel.Visible = false;
                }
            }

            // ===== 上（追加） =====
            //if (clientCursorPos.Y <= 30) // 上から30px以内
            //{
            //    if (!TopMenuPanel.Visible)
            //    {
            //        TopMenuPanel.Visible = true;
            //        TopMenuPanel.BringToFront();
            //    }
            //}
            //else
            //{
            //    if (TopMenuPanel.Visible)
            //    {
            //        TopMenuPanel.Visible = false;
            //    }
            //}
        }

        public void PlayerPanel_DoubleClick(object sender, EventArgs e)
        {


            if (config_class.config_bool_read("ダブルクリックでフルスクリーン有効") == true)
            {
                ToggleFullScreen();
            }
        }
        public void ToggleFullScreen()
        {
            if (!_isFullScreen)
            {
                _mainLayout.RowStyles[0].Height = 0; // MenuStripの行を詰める
                _mainLayout.RowStyles[2].Height = 0; // コントロールの行を詰める
                _prevBorderStyle = this.FormBorderStyle;
                _prevWindowState = this.WindowState;

                // 一旦レイアウトから外してForm直下に追加
                _mainLayout.Controls.Remove(BottomControlPanel);
                this.Controls.Add(BottomControlPanel);

                // 先にフォームをフルスクリーンにする（サイズを確定させる）
                this.FormBorderStyle = FormBorderStyle.None;
                this.WindowState = FormWindowState.Maximized;

                // フルスクリーン化後の「実際のサイズ」を使って位置を決める
                BottomControlPanel.Dock = DockStyle.None;
                BottomControlPanel.Width = this.DisplayRectangle.Width; // ClientSizeより確実
                                                                        // BottomControlPanel.Height = 130;
                BottomControlPanel.Left = 0;
                // 計算を「Formの高さ - パネルの高さ」に固定
                BottomControlPanel.Top = this.DisplayRectangle.Height - BottomControlPanel.Height;

                BottomControlPanel.Visible = false;
                BottomControlPanel.BringToFront();

                TopMenuPanel.Visible = false;
                _isFullScreen = true;
                capter_menuStrip.Visible = false;
            }
            else
            {
                _mainLayout.RowStyles[0].SizeType = SizeType.AutoSize;
                _mainLayout.RowStyles[2].SizeType = SizeType.AutoSize;
                this.FormBorderStyle = _prevBorderStyle;
                this.WindowState = _prevWindowState;

                this.Controls.Remove(BottomControlPanel);
                _mainLayout.Controls.Add(BottomControlPanel, 0, 2);
                BottomControlPanel.Dock = DockStyle.Fill;
                BottomControlPanel.Visible = true;

                TopMenuPanel.Visible = true;
                _isFullScreen = false;
                capter_menuStrip.Visible = true;


            }
        }

      

        public void PositionSlider_MouseMove(object sender, MouseEventArgs e)
        {

            if (!_pos_slidr_isDragging) return;

            SetSliderValueFromMouse(e.X);
        }
        private void SetSliderValueFromMouse(int mouseX)
        {
            double ratio = (double)mouseX / PositionSlider.Width;

            ratio = Math.Max(0, Math.Min(1, ratio));

            int newValue = (int)(PositionSlider.Minimum +
                (PositionSlider.Maximum - PositionSlider.Minimum) * ratio);


            PositionSlider.Value = newValue;
        }
        public void PositionSlider_MouseUp(object sender, MouseEventArgs e)
        {


            _pos_slidr_isDragging = false;

            double seconds = PositionSlider.Value;
            _myplayer.Seek(seconds);
        }



        public void ListSlider_MouseDown(object sender, MouseEventArgs e)
        {

            _list_slidr_isDragging = true;

            //// ★ クリック位置で即ジャンプ（WPFと同じ挙動）
            SetListValueFromMouse(e.X);
        }

        public void ListSlider_MouseMove(object sender, MouseEventArgs e)
        {
            if (!_list_slidr_isDragging) return;

            SetSliderValueFromMouse(e.X);
        }
        private void SetListValueFromMouse(int mouseX)
        {
            double ratio = (double)mouseX / ListSlider.Width;

            ratio = Math.Max(0, Math.Min(1, ratio));

            int newValue = (int)(ListSlider.Minimum +
                (ListSlider.Maximum - ListSlider.Minimum) * ratio);

            if (ListSlider.Maximum >= main_video_count)
            {
                ListSlider.Value = newValue;
            }
            lbl_Listsize.Text = newValue.ToString() + "/" + main_video_lists.Count().ToString();

        }
        public void ListSlider_MouseUp(object sender, MouseEventArgs e)
        {

            _list_slidr_isDragging = false;

            int Value = ListSlider.Value;
            main_video_count = Value;
            if (Value >= 0 && Value < main_video_lists.Count)
            {
                string url = main_video_lists[Value];

                if (System.Text.RegularExpressions.Regex.IsMatch(url, config_class.config_text_read("streamlinkで取得するURLの正規表現"), System.Text.RegularExpressions.RegexOptions.IgnoreCase))
                {
                    return;
                }
                else
                {

                    url_replace(url);
                }
            }

        }
    
        private  void url_replace(String url)
        {
            nokori_jikan = 1;


            if (string.IsNullOrEmpty(url))
            {
                return;
            }

          
            currentFilePath = url;
            _videoState.Full_path = url;
            Double db_time = 0;

            if (_myplayer.IsMpvRunning)
            {

                _myplayer.url_replace(url, db_time);
            }
            else
            {
                StartMpv(url);

            }

        }
    

        public void DVD_Play()
        {
            StartMpv("dvd://");

        }
        public void Blueray_Play()
        {
            StartMpv("bd://");

        }
        public void open_mp4_folder()
        {
            if (string.IsNullOrEmpty(currentFilePath) == false)
            {
                String dir_path = "";
                try
                {
                    dir_path = System.IO.Path.GetDirectoryName(currentFilePath);
                    if (System.IO.Directory.Exists(currentFilePath) == false)
                   {
                    Process.Start(new ProcessStartInfo
                    {
                        FileName = dir_path,
                        UseShellExecute = true
                    });
                }


                       }
                catch (System.Exception ex)
                {
                  

                }
            }

        }

        public void a_marker_creat()
        {
           
                _myplayer.show_text("A地点を作成");
           
            _a_maker = _timePos;

        }
        public void b_marker_creat()
        {
            _myplayer.show_text("B地点を作成");
            _b_maker = _timePos;

        }
        private void m3u8_title_replace_Tick(object sender, EventArgs e)
        {
            if (System.Text.RegularExpressions.Regex.IsMatch(currentFilePath, config_class.config_text_read("streamlinkで取得するURLの正規表現"), System.Text.RegularExpressions.RegexOptions.IgnoreCase) ||
      System.Text.RegularExpressions.Regex.IsMatch(currentFilePath, @"\.m3u8", RegexOptions.IgnoreCase))
            {
                if (config_class.config_bool_read("番組名を自動書き換え") == true)
                {
                    title_replace();
                }
            }
            
        }
        public void reload()
        {

            _myplayer.abema_cm_reload(currentFilePath);

        }
        private void abemaTV_cm_reaload_Tick(object sender, EventArgs e)
        {

            if (config_class.config_bool_read("CM自動リロードを有効") == true)
            {
                if (Regex.IsMatch(currentFilePath, @"(radiko.jp|abema.tv\/now-on-air|fastv.jp|linear\-abematv|amagi.tv)", RegexOptions.IgnoreCase))
                {



                    double pos = _m3u8_timePos;

                    if (pos > lastPos)
                    {


                        lastPos = pos;
                        abema_cm_reload_lastMoveTime = DateTime.Now;


                    }
                    else
                    {


                    }
                   String reload_time_st = config_class.config_text_read("自動リロード判定する停止秒数");


                    
                    int reload_time_int = 60;
                    if (string.IsNullOrEmpty(reload_time_st))
                    {
                        reload_time_st = "60";
                       




                    }
                    try {

                        reload_time_int = int.Parse(reload_time_st);
                }
                catch (System.Exception ex)
                {


                }

              
                if ((DateTime.Now - abema_cm_reload_lastMoveTime).TotalSeconds > reload_time_int)
                        {


                            _myplayer.abema_cm_reload(currentFilePath);
                            abema_cm_reload_lastMoveTime = DateTime.Now;
                        }
                   
                }
            }
         

        }
        private void a_b_LoopTimer_Tick(object sender, EventArgs e)
        {
            if (!_a_b_isLooping) return;

            double current = _timePos;

            if (current >= _b_maker)
            {
                _myplayer.Seek(_a_maker);
            }
        }
        public void ab_loop_start()
        {
            _myplayer.show_text("A-Bループ開始");
            if (_a_maker >= 0 && _b_maker > _a_maker)
            {
                _a_b_isLooping = true;

                // 最初にAへジャンプ
                _myplayer.Seek(_a_maker);

                _a_b_loopTimer.Start();

            }
        }
       

      
      
       
        public void mute_func()
        {
          
           
         _myplayer.ToggleMute();

        }
        public void audio_delay_up()
        {
         
            _myplayer.audio_delay_up();

        }
        public void audio_delay_down()
        {
            _myplayer.audio_delay_down();

        }
       
        public void ss_func()
        {
         

            _myplayer.Screenshot();

        }
        public void button_SaveSubtitleDelay_Click()
        {
            if (System.IO.File.Exists(currentFilePath))
            {
                String currentSubtitlePath = Path.ChangeExtension(currentFilePath, ".srt");
                SrtTimeShifter.ApplySubDelayToSrt(currentSubtitlePath, _currentSubDelay);
            }
        }

        public void record_url()
        {
            if (System.IO.File.Exists(currentFilePath))
            {
                return;
            }

            String download_folder = "";
            bool folder_bool = false;
            if (!string.IsNullOrWhiteSpace(config_class.config_text_read("録画動画を保存するフォルダのパス")) &&
                            System.IO.Directory.Exists(config_class.config_text_read("録画動画を保存するフォルダのパス")))
            {
                download_folder = config_class.config_text_read("録画動画を保存するフォルダのパス");
                folder_bool = true;
            }

            if (System.Text.RegularExpressions.Regex.IsMatch(currentFilePath, "https?:", System.Text.RegularExpressions.RegexOptions.IgnoreCase))
            {
                string date_st = DateTime.Now.ToString("yyyy年M月d日HH時mm分");

                String rec_title = _videoState.channel_name + "_"+ _videoState.bangumi_title+ "_"+date_st+".mp4";
                rec_title = filename.FileName_repalce(rec_title);

                if (System.Text.RegularExpressions.Regex.IsMatch(currentFilePath, config_class.config_text_read("streamlinkで取得するURLの正規表現"), System.Text.RegularExpressions.RegexOptions.IgnoreCase))
                {
                    
                   
                    if (folder_bool == true)
                    {
                        Download_class.DownloadStream(currentFilePath, rec_title);

                    }
                    else
                    {
                        Download_class.DownloadStream(currentFilePath, download_folder+"/"+ rec_title);

                    }
                }
                else
                {
                    if (Regex.IsMatch(currentFilePath, @"\.m3u8", RegexOptions.IgnoreCase))
                    {
                      
                        if (folder_bool == true)
                        {
                            Download_class.Download_Ytdlp_nopart(currentFilePath, download_folder + "/" + rec_title);
                        }
                        else
                        {
                            Download_class.Download_Ytdlp_nopart(currentFilePath, rec_title);


                        }
                    }
                    else
                    {
                        if (folder_bool == true)
                        {

                            Download_class.Download_Ytdlp(currentFilePath);
                        }
                        else
                        {

                        Download_class.Download_Ytdlp_folder(currentFilePath,download_folder);

                        }

                    }
                    }
                }

           

        }
        public void StopMpv()
        {
            _a_b_isLooping = false;

            if (config_class.config_bool_read("ボリュームを保存") == true)
            {
                int currentVol = volume_Slider.Value;
                config_class.save_config_file("ボリューム数", currentVol.ToString());

            }
            config_class.save_config_file("ミュート", bool_to_text.to_st(_mute_bool));

            if (config_class.config_bool_read("起動時SPEED変更") == true)
            {
                config_class.save_config_file("起動時SPEED数", _currentSpeed.ToString());

            }



            // loadingGif.Visible = false;

            _myplayer.StopMpv(currentFilePath);
            if (System.Text.RegularExpressions.Regex.IsMatch(currentFilePath, config_class.config_text_read("streamlinkで取得するURLの正規表現"), System.Text.RegularExpressions.RegexOptions.IgnoreCase) ||
                System.Text.RegularExpressions.Regex.IsMatch(currentFilePath, @"\.m3u8", RegexOptions.IgnoreCase))
            {
            }
            else
            {
                if (config_class.config_bool_read("レジューム機能") == true ||
                    config_class.config_bool_read("再生時にDB更新を有効") == true)
                {
            
                    //レジューム保存

                    sql_class.time_update(currentFilePath, _timePos);
                }
            }

        }
        private async void trackBarSpeed_Scroll(object sender, EventArgs e)
        {
            if (_myplayer == null || !_myplayer.IsMpvRunning)
                return;
            double speed = Speed_Slider.Value / 10.0;

            Speed_change(speed);

            speed_label.Text = speed.ToString();

        }
        private void trackBarVolume_Scroll(object sender, EventArgs e)
        {
            if (_myplayer == null || !_myplayer.IsMpvRunning)
                return;

            String vol_st = volume_Slider.Value.ToString();
            volume_label.Text = vol_st;
            if (int.TryParse(vol_st, out int vol_int))
            {
                _volume = vol_int;
                _myplayer.VolumeChange(vol_int);
            }
        }
        private void Form1_MouseWheel(object sender, MouseEventArgs e)
        {
            // Delta はホイールが1回カチッっとなると、+120/-120という値になる。
            // よって、120で割ってあげれば解りやすい値になる。

            if (config_class.config_bool_read("マウスホイール") == true)
            {
                int wheel_int = (e.Delta / 120);
                if (wheel_int == 1)
                {
                    if (config_class.config_int_read("マウスホイールの動作") == 1)
                    {

                        next_movie();
                    }
                    if (config_class.config_int_read("マウスホイールの動作") == 2)
                    {

                        NextSeek();
                    }
                    if (config_class.config_int_read("マウスホイールの動作") == 3)
                    {
                        VolumeUp();
                    }
                    if (config_class.config_int_read("マウスホイールの動作") == 4)
                    {
                        ZoomUp();
                    }
                    if (config_class.config_int_read("マウスホイールの動作") == 5)
                    {
                        SpeedUp();
                    }
                }
                if (wheel_int == -1)
                {
                    if (config_class.config_int_read("マウスホイールの動作") == 1)
                    {

                        prev_movie();
                    }
                    if (config_class.config_int_read("マウスホイールの動作") == 2)
                    {

                        PrevSeek();
                    }
                    if (config_class.config_int_read("マウスホイールの動作") == 3)
                    {
                        VolumeDown();
                    }
                    if (config_class.config_int_read("マウスホイールの動作") == 4)
                    {
                        ZoomDown();
                    }
                    if (config_class.config_int_read("マウスホイールの動作") == 4)
                    {
                        SpeedDown();
                    }
                }
            }
        }

        private void VolumeUp()
        {

            if (volume_Slider.Value <= volume_Slider.Maximum)
            {
                _myplayer.VolumeUp();
                volume_Slider.Value += 5;
            }

        }

        private void VolumeDown()
        {
            if (volume_Slider.Value > 0)
            {
                _myplayer.VolumeDown();
                volume_Slider.Value -= 5;
            }

        }
        public void ver_mes_bosx()
        {
            Version ins = new Version();

            ins.Show();

        }
        public async void play_ping()
        {
           await  ping_m3u8.Main();




        }

        public async void StartMpv(string pathOrUrl)
        {
            String mpv_path = config_class.config_text_read("mpvのパス");
            if (!string.IsNullOrWhiteSpace(mpv_path))
            {

            }
            else
            {


                MessageBox.Show("mpvのパスの設定が空です。");
                return;
            }

            if (System.IO.File.Exists(mpv_path))
            {

            }
            else
            {
                MessageBox.Show(mpv_path + ":mpv.exeが無いです。");
                return;


            }
           
                String ytdlp_path = config_class.config_text_read("yt-dlpのパス");
                if (!string.IsNullOrWhiteSpace(ytdlp_path))
                {

                   
            }
            else
            {
                MessageBox.Show("yt-dlpのパスの設定が空です。");
                return;
            }

                if (System.IO.File.Exists(ytdlp_path))
                {

                }
                else
                {
                    MessageBox.Show(ytdlp_path + ":yt-dlp.exeが無いです。");
                    return;


                }
            String add_comand = "";
            if (config_class.config_bool_read("mpvの追加起動コマンドを有効") == true)
            {
                if (string.IsNullOrEmpty(config_class.config_text_read("mpvの追加起動コマンド")) == false)
                {
                    add_comand = config_class.config_text_read("mpvの追加起動コマンド");
                }



            }
                String force_window = "";

            if (config_class.config_bool_read("force-window=yesを起動引数に入れる") == true)
            {
                force_window = " --force-window=yes";
            }
            String idle_yes = "";
            if (config_class.config_bool_read("idle=yesを起動引数に入れる") == true)
            {
                idle_yes = " --idle=yes";
            }

            nokori_jikan = 1;
            if (string.IsNullOrEmpty(pathOrUrl))
            {
                return;
            }
            string PipeName = "mpv-pipe-" + Guid.NewGuid().ToString("N");
            _videoState.Full_path = pathOrUrl;
            currentFilePath = pathOrUrl;


            if (InvokeRequired)
            {
                Invoke(new Action(() => StartMpv(pathOrUrl)));
                return;
            }

            StopMpv();





         
            String mpv_log_text = "";
            if (config_class.config_bool_read("mpvのログを有効") == true)
            {

                mpv_log_text = " --log-file=mpv_log.txt --msg-level=all=debug";


            }
            String thread_text = "";
            if (config_class.config_bool_read("スレッド有効") == true)
            {
                if (string.IsNullOrEmpty(config_class.config_text_read("スレッド数")) == false)
                {
                    thread_text = " --vd-lavc-threads=" + config_class.config_text_read("スレッド数");

                }
            }
            String cache_text = "";
            if (config_class.config_bool_read("キャッシュを有効") == true)
            {   //--cache-pause=yes --cache-pause-initial=yes
                cache_text = " --cache=yes";
                if (string.IsNullOrEmpty(config_class.config_text_read("キャッシュサイズ")) == false)
                {
                    cache_text = cache_text + " --demuxer-max-bytes=" + config_class.config_text_read("キャッシュサイズ") + "M";

                }
                if (string.IsNullOrEmpty(config_class.config_text_read("キャッシュ時間")) == false)
                {
                    cache_text = cache_text + " --cache-secs=" + config_class.config_text_read("キャッシュ時間");


                }
                if (config_class.config_bool_read("キャッシュが溜まるまで待つ") == true)
                {
                    cache_text = cache_text + " --cache-pause=yes --cache-pause-initial=yes";

                }

            }



            string videoEq = "";
            if (config_class.config_bool_read("ビデオイコライザーを保存") == true)
            {

                if (string.IsNullOrEmpty(config_class.config_text_read("video_setting")) == false)
                {

                    try
                    {
                        string[] elements = config_class.config_text_read("video_setting").Split(',', StringSplitOptions.RemoveEmptyEntries);

                        videoEq =
         $" --brightness={elements[0]} " +
         $"--contrast={elements[1]} " +
         $"--gamma={elements[2]} " +
         $"--saturation={elements[3]} " +
         $"--hue={elements[4]}";
                    }
                    catch (System.Exception ex)
                    {

                        Debug.WriteLine(ex.Message + ex.StackTrace);



                    }
                }
            }
       
            String srt_sub = "";
            if (config_class.config_bool_read("SRT字幕の設定を有効") == true)
            {
               if(string.IsNullOrEmpty(config_class.config_text_read("字幕のフォントサイズ")) == false)
            {
                    srt_sub = srt_sub+ $" --sub-font-size={config_class.config_text_read("字幕のフォントサイズ")}";
                }
                if (string.IsNullOrEmpty(config_class.config_text_read("字幕のフォント名")) == false)
                {
                    srt_sub = srt_sub + $" --sub-font=\"{config_class.config_text_read("字幕のフォント名")}\"";
                }
                if (string.IsNullOrEmpty(config_class.config_text_read("字幕のフォントカラー")) == false)
                {
                    srt_sub = srt_sub + $" --sub-color={config_class.config_text_read("字幕のフォントカラー")}";
                }
                if (string.IsNullOrEmpty(config_class.config_text_read("字幕の枠の大きさ")) == false)
                {
                    srt_sub = srt_sub + $" --sub-border-size={config_class.config_text_read("字幕の枠の大きさ")}";
                }
                if (string.IsNullOrEmpty(config_class.config_text_read("字幕の枠の色")) == false)
                {
                    srt_sub = srt_sub + $" --sub-border-color={config_class.config_text_read("字幕の枠の色")}";
                }
                if (string.IsNullOrEmpty(config_class.config_text_read("字幕の影のオフセット")) == false)
                {
                    srt_sub = srt_sub + $" --sub-shadow-offset={config_class.config_text_read("字幕の影のオフセット")}";
                }
                if (string.IsNullOrEmpty(config_class.config_text_read("字幕の縦位置")) == false)
                {
                    srt_sub = srt_sub + $" --sub-pos={config_class.config_text_read("字幕の縦位置")}";
                }
            }
         
                String hwdec_text = "";
            if (config_class.config_bool_read("hwdecを有効") == true &&
                string.IsNullOrEmpty(config_class.config_text_read("hwdecの値")) == false)
            {
                hwdec_text = $" --hwdec={config_class.config_text_read("hwdecの値")}";
            }

            String gpuapi_text = "";
            if (config_class.config_bool_read("gpu-apiを有効") == true &&
                string.IsNullOrEmpty(config_class.config_text_read("gpu-apiの値")) == false)
            {
                gpuapi_text = $" --gpu-api={config_class.config_text_read("gpu-apiの値")}";
            }

            String scale_text = "";
            if (config_class.config_bool_read("scaleを有効") == true &&
                string.IsNullOrEmpty(config_class.config_text_read("scaleの値")) == false)
            {
                scale_text = $" --scale={config_class.config_text_read("scaleの値")}";
            }

            String interpolation_text = "";
            if (config_class.config_bool_read("interpolationを有効") == true &&
                string.IsNullOrEmpty(config_class.config_text_read("interpolationの値")) == false)
            {
                interpolation_text = $" --interpolation={config_class.config_text_read("interpolationの値")}";
            }

            String vo_text = "";
            if (config_class.config_bool_read("voを有効") == true)
            {
                vo_text = $" --vo={config_class.config_text_read("voの値")}";
            }

            String glsl_text = "";
            if (config_class.config_bool_read("glslを有効") == true &&
                string.IsNullOrEmpty(config_class.config_text_read("glslのパス")) == false)
            {
                glsl_text = " --glsl-shader=\"" + config_class.config_text_read("glslのパス") + "\"";

            }



            String pipe_Arguments = $" --input-ipc-server=\\\\.\\pipe\\{PipeName}";
            String Arguments = $"{force_window}{idle_yes}{cache_text}{thread_text}{glsl_text}{hwdec_text}{gpuapi_text}{scale_text}{interpolation_text}{vo_text}{videoEq}{mpv_log_text}{srt_sub}{add_comand}";



            if (System.Text.RegularExpressions.Regex.IsMatch(pathOrUrl, config_class.config_text_read("streamlinkで取得するURLの正規表現"), System.Text.RegularExpressions.RegexOptions.IgnoreCase))
            {

                String steam_path = config_class.config_text_read("streamlinkのパス");
                if (!string.IsNullOrWhiteSpace(steam_path))
                {

                   
                }
                else
                {
                    MessageBox.Show("streamlinkのパスの設定が空です。");
                    return;
                }

                if (System.IO.File.Exists(steam_path))
                {

                }
                else
                {
                    MessageBox.Show(steam_path + ":streamlink.exeが無いです。");
                    return;


                }
                await Task.Run(() =>
                         _myplayer.StartStream(pathOrUrl, Arguments, pipe_Arguments, PipeName,mpv_path, steam_path)
                 );

                return;
            }
            else
            {
                


                await Task.Run(() =>
                   _myplayer.StartMpv(pathOrUrl, Arguments, pipe_Arguments, PipeName,mpv_path, ytdlp_path,this)

                );

            }





            lblFilesize.Text = GetFileSize(pathOrUrl);




        }



        private void UpdateChapterMenu(List<MpvChapter> chapters)
        {
            // ① 一旦チャプターメニュー削除
            if (menuChapters != null)
            {
                capter_menuStrip.Items.Remove(menuChapters);
            }

            // ② チャプター無いなら何も表示しない
            if (chapters == null || chapters.Count == 0)
            {
                return;
            }

            menuChapters = new ToolStripMenuItem("チャプター");


            for (int i = 0; i < chapters.Count; i++)
            {
                var ch = chapters[i];

                var item = new ToolStripMenuItem(ch.Display);
                item.Tag = i;
                item.Click += Chapter_Click;

                menuChapters.DropDownItems.Add(item);
            }
            capter_menuStrip.Items.Add(menuChapters);
            this.Controls.Add(capter_menuStrip);
        }
        private void Chapter_Click(object sender, EventArgs e)
        {
            if (sender is ToolStripMenuItem item && item.Tag is int index)
            {
                _myplayer.ChangeChapter(index);

            }
        }
        private void HandleMpvMessage(string json)
        {


            if (string.IsNullOrWhiteSpace(json))
                return;

            json = json.Trim();

            // JSON で始まっていない行はログなので無視
            if (!json.StartsWith("{") && !json.StartsWith("["))
                return;


            JObject obj = null;
            try
            {

                obj = JObject.Parse(json);
            }
            catch (System.Exception ex)
            {
                error.write_error_log(ex.Message + ex.StackTrace);
                Debug.WriteLine(ex.Message + ex.StackTrace);
                return;
            }
            if (obj == null)
                return;




            string evt = (string)obj["event"];

            switch (evt)
            {
                case "file-loaded":

                  
                    if (config_class.config_bool_read("起動時にパンスキャン") == true)
                    {

                        _myplayer.Video.panscan_delay();
                    }
                
               
                    if (config_class.config_bool_read("オーディオイコライザーを保存") == true)
                    {
                        string audio_eq_filter = "";
                        if (config_class.config_bool_read("オーディオイコライザーを保存") == true)
                        {
                            if (string.IsNullOrEmpty(config_class.config_text_read("オーディオイコライザーの値")) == false)
                            {
                                string eqText = config_class.config_text_read("オーディオイコライザーを保存");
                                try
                                {
                                    double[] eq = eqText
                                        .Split(',')
                                        .Select(s => double.Parse(s, CultureInfo.InvariantCulture))
                                        .ToArray();

                                    int[] freq = { 31, 62, 125, 250, 500, 1000, 2000, 4000, 8000, 16000 };

                                    var filters = new List<string>();

                                    for (int i = 0; i < 10; i++)
                                    {
                                        filters.Add($"equalizer=f={freq[i]}:g={eq[i].ToString(System.Globalization.CultureInfo.InvariantCulture)}");
                                    }

                                    audio_eq_filter = "lavfi=[" + string.Join(",", filters) + "]";

                                }
                                catch (System.Exception ex)
                                {
                                    Debug.WriteLine(ex.Message + ex.StackTrace);



                                }
                            }
                        }
                        if (
                                              string.IsNullOrEmpty(audio_eq_filter) == false)
                        {

                            _myplayer.Audio.audio_Equalizer_start(config_class.config_text_read("オーディオエフェクトの値"));

                        }
                    }

                    if (config_class.config_bool_read("速度変更しても音程を維持する") == true)
                    {
                        _myplayer.audio_pitch_correction();
                    }
                    if (config_class.config_bool_read("ビデオエフェクトを保存") == true &&
                        string.IsNullOrEmpty(config_class.config_text_read("ビデオエフェクトの値")) == false)
                    {
                        _myplayer.Video.video_lavfi_start(config_class.config_text_read("ビデオエフェクトの値"));
                    }

                    if (config_class.config_bool_read("オーディオエフェクトを保存") == true &&
                        string.IsNullOrEmpty(config_class.config_text_read("オーディオエフェクトの値")) == false)
                    {
                        _myplayer.Audio.audio_lavfi_start(config_class.config_text_read("オーディオエフェクトの値"));


                    }
                    if (config_class.config_bool_read("起動時に360度VRモード有効") == true) {
                        vr_360mode();
                    }

                    if (config_class.config_bool_read("cropを起動時に実行") == true &&
                       string.IsNullOrEmpty(config_class.config_text_read("crop")) == false)
                    {
                        _myplayer.Video.video_crop(config_class.config_text_read("crop"));
                    }


                    if (Regex.IsMatch(currentFilePath, @"\.m3u8", RegexOptions.IgnoreCase))
                    {
                    }
                    else
                    {
                        if (config_class.config_bool_read("起動時SPEED変更") == true)
                        {

                            var str = config_class.config_text_read("起動時SPEED数");



                            if (double.TryParse(str, out double speed))
                            {
                                _currentSpeed = speed;
                                Speed_change_no_osd(speed);

                            }
                        }

                    }


                    _myplayer.VolumeChange(_volume);

                    BeginInvoke(() =>
                    {
                        volume_label.Text = _volume.ToString();
                        volume_Slider.Value = _volume;
                    });



                    if (config_class.config_bool_read("ミュート") == true)
                    {
                        mute_func();
                    }

                    if (System.Text.RegularExpressions.Regex.IsMatch(currentFilePath, config_class.config_text_read("streamlinkで取得するURLの正規表現"), System.Text.RegularExpressions.RegexOptions.IgnoreCase) ||
Regex.IsMatch(currentFilePath, @"\.m3u8", RegexOptions.IgnoreCase))
                    {
                    }
                    else
                    {

                        if (config_class.config_bool_read("レジューム機能") == true ||
                            config_class.config_bool_read("再生時にDB更新を有効") == false)
                        {
                            double db_time = sql_class.sql_add(currentFilePath);
                       
                            if (config_class.config_bool_read("レジューム機能") == true &&
                        config_class.config_bool_read("再生開始時に途中から再生する") == false)
                            {
                                if (db_time > 0)
                                    _myplayer.Seek(db_time);
                            }
                        }
                    }
                    if (config_class.config_bool_read("再生開始時に途中から再生する") == true)
                    {
                  
                        var str = config_class.config_text_read("開始する時間");



                        if (double.TryParse(str,
                            System.Globalization.NumberStyles.Float,
                            System.Globalization.CultureInfo.InvariantCulture,
                            out double minutes))
                        {
                            double seconds = minutes * 60;
                            _myplayer.Seek(seconds);

                        }

                    }

                    if (config_class.config_bool_read("解像度を下げる") == true)
                    {
                        String fix_scale=(config_class.config_text_read("下げる解像度のwidth"));
                        if(!string.IsNullOrEmpty(fix_scale)){
                            _myplayer.Video.video_scale_fix(fix_scale);
                        }
                   

                        
                        }



                    break;

                case "end-file":
                    if (nokori_jikan < 0.5)
                    {
                        BeginInvoke(() =>
                    {

                        OnVideoEnded();
                    });
                    }

                    break;


            }
            var dataToken = obj["data"];

            if (dataToken == null || dataToken.Type == JTokenType.Null)
                return;

            string name = obj["name"]?.ToString();

            switch (name)
            {
                case "time-remaining":

                    nokori_jikan = dataToken.Value<double>();

                    break;
                case "sub-delay":
                    _currentSubDelay = dataToken.Value<double>();
                    break;
                case "mute":
                  
                    _mute_bool = dataToken.Value<bool>();
                    config_class.save_config_file("ミュート", bool_to_text.to_st(_mute_bool));

                    break;
                case "volume":
                    
                    int vol = (int)Math.Round(dataToken.Value<double>());
                    _volume = vol;

                    BeginInvoke(() =>
                    {
                        vol = Math.Max(volume_Slider.Minimum,
                              Math.Min(volume_Slider.Maximum, vol));

                        volume_Slider.Value = vol;
                        volume_label.Text = vol.ToString();
                    });
                    break;

                case "width":
                    _videoWidth = dataToken.Value<double>();
                    _videoState.videoWidth = dataToken.Value<double>();
                    UpdateResolutionLabel();
                    break;
                case "chapter-list":
                    var chapters = JsonSerializer.Deserialize<List<MpvChapter>>(dataToken.ToString());


                    cap_size = chapters.Count;

                    if (config_class.config_bool_read("チャプターを上部メニューに表示") == true)
                    {
                        BeginInvoke(() =>
                    {
                        UpdateChapterMenu(chapters);
                    });
                    }
                    break;

                case "track-list":

                    var tracks = JsonSerializer.Deserialize<List<MpvTrack>>(dataToken.ToString());

                    BeginInvoke(() =>
                    {
                        if (config_class.config_bool_read("DVDの音声と字幕の自動選択を有効") == true)
                        {
                            if (config_class.config_int_read("DVDの自動選択設定") == 1)
                            {
                                AutoSelectJapaneseAudioAndSubtitle(tracks);
                            }
                            if (config_class.config_int_read("DVDの自動選択設定") == 2)
                            {
                                AutoSelectEnglishAudioAndSubtitle(tracks);
                            }
                        }
                        if (config_class.config_bool_read("字幕と音声選択メニューを表示") == true)
                        {
                            UpdateTrackMenu(tracks); // ← ここに
                        }

                    });




                    break;

                case "playlist":

                    // 重複防止用
                    HashSet<string> urlSet = new HashSet<string>(youtube_play_lists_url);

                    if (dataToken is JArray arr)
                    {
                        bool isReady = arr.Any(x => (bool?)x["playing"] == true);

                        if (!isReady)
                        {
                            // まだ途中なので無視
                            return;
                        }
                        youtube_play_lists_url.Clear();
                        youtube_play_lists_title.Clear();

                        foreach (var item in arr.OfType<JObject>())
                        {
                          
                            string filename = item["filename"]?.ToString();
                            string title = item["title"]?.ToString();
                           
                                if (string.IsNullOrWhiteSpace(filename))
                                continue;

                            // --- 現在再生中URLを除外 ---
                            if (string.Equals(filename, currentFilePath, StringComparison.OrdinalIgnoreCase))
                                continue;

                            // --- 重複除外 ---
                            if (!urlSet.Add(filename))
                                continue;
                            if (!Regex.IsMatch(filename, @"^https?://", RegexOptions.IgnoreCase))
                                continue;

                            if (string.Equals(filename, currentFilePath, StringComparison.OrdinalIgnoreCase))
                                continue;

                            if (!urlSet.Add(filename))
                                continue;
                            youtube_play_lists_url.Add(filename);
                            youtube_play_lists_title.Add(
                                string.IsNullOrWhiteSpace(title) ? filename : title
                            );
                        }
                    }

                    if (youtube_play_lists_url.Count > 1)
                    {
                        if (config_class.config_bool_read("プレイリストをメニューに表示") == true)
                        {

                            BeginInvoke(() =>
                        {
                            UpdatePlaylistMenu(youtube_play_lists_title, youtube_play_lists_url);
                        });
                        }
                    }

                    break;


                case "file-size":
                    _filesize = dataToken.Value<double>();
                    _videoState.filesize = dataToken.Value<double>();
                    UpdateResolutionLabel();
                    break;
              
                case "height":
                    _videoHeight = dataToken.Value<double>();
                    _videoState.videoHeight = dataToken.Value<double>();
                    UpdateResolutionLabel();
                    break;
                case "media-title":
                    _videoState.video_title = dataToken.ToString();

              
                    BeginInvoke(() =>
                    {
                        this.Text = currentFilePath;   
                        lbl_title.Text = dataToken.ToString();
                    });

                    title_replace();
                    break;





                case "video-codec":
                    _videoState.video_codec = dataToken.ToString();

                    break;

                case "audio-codec":

                    _videoState.audio_codec = dataToken.ToString();
                    break;

                case "video-bitrate":
                    _videoState.video_bitrate = dataToken.ToString(); ;
                    break;
                case "container-fps":
                    _videoState.container_fps = dataToken.ToString(); ;

                    break;
                case "estimated-vf-fps":
                    _videoState.estimated_fps = dataToken.ToString(); ;

                    break;

                case "audio-bitrate":
                    _videoState.audio_bitrate = dataToken.ToString(); ;
                    break;


                case "duration":

                    if (System.Text.RegularExpressions.Regex.IsMatch(currentFilePath, @"\.m3u8)", System.Text.RegularExpressions.RegexOptions.IgnoreCase))
                    {

                    }
                    else if (System.Text.RegularExpressions.Regex.IsMatch(currentFilePath,
                             config_class.config_text_read("streamlinkで取得するURLの正規表現"),
                             System.Text.RegularExpressions.RegexOptions.IgnoreCase))
                    {
                    }

                    else
                    {
                        _duration = dataToken.Value<double>();
                        _videoState.duration = dataToken.Value<double>();
                        BeginInvoke(() =>
                        {
                            PositionSlider.Minimum = 0;
                            PositionSlider.Maximum = (int)(_duration);
                        });
                    }
                    break;

                case "time-pos":

                    if (System.Text.RegularExpressions.Regex.IsMatch(currentFilePath, config_class.config_text_read("streamlinkで取得するURLの正規表現"), System.Text.RegularExpressions.RegexOptions.IgnoreCase) ||
         System.Text.RegularExpressions.Regex.IsMatch(currentFilePath, @"\.m3u8)", RegexOptions.IgnoreCase))
                    {

                        _m3u8_timePos = dataToken.Value<double>();
                    }
                  
                    else
                    {
                        _timePos = dataToken.Value<double>();

                        BeginInvoke(() =>
                        {
                            if (!_pos_slidr_isDragging && PositionSlider.Maximum > 0)
                                if (PositionSlider.Maximum >= (int)(_timePos))
                                {
                                    PositionSlider.Value = (int)(_timePos);
                                }
                        });
                    }
                    UpdateTimeLabel();
                    break;
            }
         
            

        }

        private void title_replace()
        {
           
                if (System.Text.RegularExpressions.Regex.IsMatch(currentFilePath, @"amagi.tv.+?rakuten", System.Text.RegularExpressions.RegexOptions.IgnoreCase))
                {
                   
                        String title2 = title_generate.Get_title(currentFilePath, title_generate._rakuten_ChannelNameMap, 2, "rakuten") + "(楽天)";
                        (string title, string desc, String image_path, String category) tuple_epg = default;

                        if (config_class.config_int_read("表示のEPG取得先") == 3 ||
                     config_class.config_int_read("表示のEPG取得先") == 2)
                        {

                            tuple_epg = title_generate.Get_bungumi_title(currentFilePath, 2, "karenda_epg.xml", title_generate._rakuten_epg_ChannelNameMap, doc_karenda_epg);

                        }

                        if (config_class.config_int_read("表示のEPG取得先") == 4)
                        {

                            tuple_epg = title_generate.Get_bungumi_title(currentFilePath, 2, "jp_epg_26f0ce.xml", title_generate._rakuten_epg_ChannelNameMap, doc_jp_epg_26f0ce);

                        }

                        if (config_class.config_int_read("表示のEPG取得先") == 1)
                        {
                            _title = title2;

                        }
                        else
                        {
                            _title = title2 + tuple_epg.title;
                        BeginInvoke(() =>
                        {

                            if (lbl_desc.Text != tuple_epg.desc)
                            {
                                lbl_desc.Text = tuple_epg.desc;
                            }
                        });
                        _videoState.bangumi_title = tuple_epg.title;
                            _videoState.description = tuple_epg.desc;



                        }
                        _videoState.channel_name = title2;
                    BeginInvoke(() =>
                    {
                        if (!this.Text.Equals(_title))
                        {
                            this.Text = _title;
                        }
                        if (!lbl_title.Equals(_title))
                        {
                            lbl_title.Text = _title;
                        }
                });

                return;
                }
                if (System.Text.RegularExpressions.Regex.IsMatch(currentFilePath, @"livetv.fastv.jp", System.Text.RegularExpressions.RegexOptions.IgnoreCase))
                {

                    String title2 = title_generate.Get_title(currentFilePath, title_generate._fast_channelMap, 2, "fast") + "(fast)";
                    (string title, string desc, String image_path, String category) tuple_epg = default;

                    if (config_class.config_int_read("表示のEPG取得先") == 3 ||
                 config_class.config_int_read("表示のEPG取得先") == 2 ||
                 config_class.config_int_read("表示のEPG取得先") == 4)
                    {

                        tuple_epg = title_generate.Get_bungumi_title(currentFilePath, 2, "karenda_epg.xml", title_generate._fast_epg_channelMap, doc_karenda_epg);

                    }



                    if (config_class.config_int_read("表示のEPG取得先") == 1)
                    {
                        _title = title2;

                    }
                    else
                    {
                        _title = title2 + tuple_epg.title;
                        BeginInvoke(() =>
                        {
                            if (lbl_desc.Text != tuple_epg.desc)
                        {
                            lbl_desc.Text = tuple_epg.desc;
                        }
                        });
                        _videoState.bangumi_title = tuple_epg.title;
                        _videoState.description = tuple_epg.desc;



                    }
                    _videoState.channel_name = title2;
                    BeginInvoke(() =>
                    {
                        if (!this.Text.Equals(_title))
                        {
                            this.Text = _title;
                        }
                        if (!lbl_title.Equals(_title))
                        {
                            lbl_title.Text = _title;
                        }
                    });
                    return;
                }
            if (System.Text.RegularExpressions.Regex.IsMatch(currentFilePath, @"akariko-bck1.sankuria.sbs", System.Text.RegularExpressions.RegexOptions.IgnoreCase))
            {
                BeginInvoke(() =>
                {

                    (string title, string desc, String image_path, String category) tuple_epg = default;

                    if (config_class.config_int_read("表示のEPG取得先") == 2)
                    {

                        tuple_epg = title_generate.Get_bungumi_title(currentFilePath, 3, "animenosekai_epg.xml", title_generate._Epg_naori_animenosekai_Map, doc_animenosekai_epg);

                    }
                    if (config_class.config_int_read("表示のEPG取得先") == 3)
                    {

                        tuple_epg = title_generate.Get_bungumi_title(currentFilePath, 3, "karenda_epg.xml", title_generate._Epg_naori_karenda_Map, doc_karenda_epg);

                    }
                    if (config_class.config_int_read("表示のEPG取得先") == 4)
                    {

                        tuple_epg = title_generate.Get_bungumi_title(currentFilePath, 3, "jp_epg_26f0ce.xml", title_generate._Epg_naori_karenda_Map, doc_jp_epg_26f0ce);

                    }

                    String title2 = title_generate.Get_title(currentFilePath, title_generate._akari_ChannelMap, 3, "akari") + "(akari)";

                    if (config_class.config_int_read("表示のEPG取得先") == 1)
                    {
                        _title = title2;

                    }
                    else
                    {
                        _title = title2 + tuple_epg.title;
                        BeginInvoke(() =>
                        {

                            if (lbl_desc.Text != tuple_epg.desc)
                            {
                                lbl_desc.Text = tuple_epg.desc;
                            }
                            _videoState.bangumi_title = tuple_epg.title;
                            _videoState.description = tuple_epg.desc;





                        });
                    }

                    _videoState.channel_name = title2;
                    BeginInvoke(() =>
                    {
                        if (!this.Text.Equals(_title))
                        {
                            this.Text = _title;
                        }

                        if (!lbl_title.Equals(_title))
                        {
                            lbl_title.Text = _title;
                        }
                    });

                    return;
                }); 
            }     
            if (System.Text.RegularExpressions.Regex.IsMatch(currentFilePath, @"zhongying", System.Text.RegularExpressions.RegexOptions.IgnoreCase))
                {


                    (string title, string desc, String image_path, String category) tuple_epg = default;


                    if (config_class.config_int_read("表示のEPG取得先") == 2)
                    {

                        tuple_epg = title_generate.Get_bungumi_title(currentFilePath, 3, "animenosekai_epg.xml", title_generate._Epg_naori_animenosekai_Map, doc_animenosekai_epg);

                    }
                    if (config_class.config_int_read("表示のEPG取得先") == 3)
                    {

                        tuple_epg = title_generate.Get_bungumi_title(currentFilePath, 3, "karenda_epg.xml", title_generate._Epg_naori_karenda_Map, doc_karenda_epg);

                    }
                    if (config_class.config_int_read("表示のEPG取得先") == 4)
                    {

                        tuple_epg = title_generate.Get_bungumi_title(currentFilePath, 3, "jp_epg_26f0ce.xml", title_generate._Epg_naori_karenda_Map, doc_jp_epg_26f0ce);

                    }

                    String title2 = title_generate.Get_title(currentFilePath, title_generate._naori_channelMap, 3, "zhon") + "(zhon)";

                    if (config_class.config_int_read("表示のEPG取得先") == 1)
                    {
                        _title = title2;

                    }
                    else
                    {
                        _title = title2 + tuple_epg.title;
                        BeginInvoke(() =>
                        {
                            if (lbl_desc.Text != tuple_epg.desc)
                            {
                                lbl_desc.Text = tuple_epg.desc;
                            }
                            _videoState.bangumi_title = tuple_epg.title;
                            _videoState.description = tuple_epg.desc;

                            _videoState.logo_img_path = tuple_epg.image_path;
                            _videoState.category = tuple_epg.category;

                            if (lbl_category.Text != tuple_epg.category)
                            {
                                lbl_category.Text = tuple_epg.category;
                            }
                        });


                        _videoState.channel_name = title2;
                        BeginInvoke(() =>
                        {
                            if (!this.Text.Equals(_title))
                            {
                                this.Text = _title;
                            }
                            if (!lbl_title.Equals(_title))
                            {
                                lbl_title.Text = _title;
                            }
                        });

                    }
                    return;
                }
               
                if (System.Text.RegularExpressions.Regex.IsMatch(currentFilePath, @"https://linear-abematv.akamaized.net/preview/channel/[\-_a-zA-Z0-9]+/playlist.m3u8", System.Text.RegularExpressions.RegexOptions.IgnoreCase))
                {
                    String title2 = title_generate.Get_title(currentFilePath, title_generate._abemaMap, 3, "abema" + "abema低画質");
                    (string title, string desc, String image_path, String category) tuple_epg = default;


                    if (config_class.config_int_read("表示のEPG取得先") == 3 ||
                   config_class.config_int_read("表示のEPG取得先") == 2)
                    {

                        tuple_epg = title_generate.Get_abema_bungumi_title(currentFilePath, 3, "karenda_epg.xml", title_generate._Epg_naori_karenda_Map, doc_jp_epg_26f0ce);

                    }
                    if (
         config_class.config_int_read("表示のEPG取得先") == 4)
                    {

                        tuple_epg = title_generate.Get_abema_bungumi_title(currentFilePath, 3, "jp_epg_26f0ce.xml", title_generate._Epg_naori_karenda_Map, doc_jp_epg_26f0ce);

                    }

                    if (config_class.config_int_read("表示のEPG取得先") == 1)
                    {
                        _title = title2;

                    }
                    else
                    {
                        _title = title2 + tuple_epg.title;
                        BeginInvoke(() =>
                        {

                            if (lbl_desc.Text != tuple_epg.desc)
                            {
                                lbl_desc.Text = tuple_epg.desc;
                            }
                        });
                        _videoState.bangumi_title = tuple_epg.title;
                        _videoState.description = tuple_epg.desc;

                        _videoState.logo_img_path = tuple_epg.image_path;
                        _videoState.category = tuple_epg.category;



                    }
                    _videoState.channel_name = title2;
                    BeginInvoke(() =>
                    {
                        if (!this.Text.Equals(_title))
                        {
                            this.Text = _title;
                        }


                        if (!lbl_title.Equals(_title))
                        {

                            lbl_title.Text = _title;
                        }
                    });

                    return;

                }
                if (System.Text.RegularExpressions.Regex.IsMatch(currentFilePath, @"(mov3.co|ok.ru)", System.Text.RegularExpressions.RegexOptions.IgnoreCase))
                {

                    String title2 = title_generate.Get_mov3(currentFilePath) + "(mov3)";
                    (string title, string desc, String image_path, string category) tuple_epg = default;


                    if (config_class.config_int_read("表示のEPG取得先") == 2)
                    {

                        tuple_epg = title_generate.Get_mov3_bungumi_title(currentFilePath, "animenosekai_epg.xml", title_generate._mov3_epg_animenosekai_Map, doc_animenosekai_epg);

                    }
                    if (config_class.config_int_read("表示のEPG取得先") == 3)
                    {

                        tuple_epg = title_generate.Get_mov3_bungumi_title(currentFilePath, "karenda_epg.xml", title_generate._mov3_epg_karenda_Map, doc_karenda_epg);

                    }
                    if (config_class.config_int_read("表示のEPG取得先") == 4)
                    {

                        tuple_epg = title_generate.Get_mov3_bungumi_title(currentFilePath, "jp_epg_26f0ce.xml", title_generate._mov3_epg_karenda_Map, doc_karenda_epg);

                    }

                    if (config_class.config_int_read("表示のEPG取得先") == 1)
                    {
                        _title = title2;

                    }
                    else
                    {
                        _title = title2 + tuple_epg.title;
                        BeginInvoke(() =>
                        {
                            if (lbl_desc.Text != tuple_epg.desc)
                            {
                                lbl_desc.Text = tuple_epg.desc;
                            }
                        });
                        _videoState.bangumi_title = tuple_epg.desc;
                        _videoState.description = tuple_epg.title;
                        _videoState.category = tuple_epg.category;
                        _videoState.logo_img_path = tuple_epg.image_path;
                        lbl_category.Text = tuple_epg.category;
                    }
                    _videoState.channel_name = title2;


                    BeginInvoke(() =>
                    {
                        if (this.Text != _title)
                        {
                            this.Text = _title;
                        }
                        if (lbl_title.Text != _title)
                        {
                            lbl_title.Text = _title;
                        }
                    });
                    return;

                }

                if (System.Text.RegularExpressions.Regex.IsMatch(currentFilePath, @"https://radiko.jp/#\!/live/", System.Text.RegularExpressions.RegexOptions.IgnoreCase))
                {

                    String title2 = title_generate.GetRadikoStation(currentFilePath);
                    channel_class.channel_id = title2;
                if (config_class.config_int_read("表示のEPG取得先") == 1)
                { }
                else
                {


                    var current = epg.Radik_GetCurrentProgram("radiko_epg.xml", title2, doc_radiko_epg);

                    if (current != null)
                    {

                        _videoState.logo_img_path = current.Img;


                        if (string.IsNullOrEmpty(current.StationName))
                        {
                            _title = title2 + " " + current.Title;

                        }
                        else
                        {
                            _title = title2 + " " + current.StationName + " " + current.Title;

                        }
                        _videoState.channel_name = current.Title;
                        BeginInvoke(() =>
                        {
                            if (lbl_desc.Text != current.Info + current.Desc)
                            {
                                lbl_desc.Text = current.Info + current.Desc;
                            }
                            if (this.Text != _title)
                            {
                                this.Text = _title;
                            }
                            if (lbl_title.Text != _title)
                            {
                                lbl_title.Text = _title;
                            }
                        });
                        _videoState.pfm = current.Pfm;
                        _videoState.url = current.Url;

                        if (lbl_category.Text != current.Pfm)
                        {
                            lbl_category.Text = current.Pfm;
                        }




                    }
                    else
                    {
                        _title = title2;
                        _videoState.channel_name = "";

                        if (this.Text != _title)
                        {
                            this.Text = _title;
                        }
                        if (lbl_title.Text != _title)
                        {
                            lbl_title.Text = _title;
                        }





                    }
                }

                }
          
        }
        private void AutoSelectEnglishAudioAndSubtitle(List<MpvTrack> tracks)
        {
            var jaCodes = new[] { "jpn", "ja", "jp", "japanese" };
            var enCodes = new[] { "eng", "en", "english" };

            var jpSub = tracks.FirstOrDefault(t =>
                t.type == "sub" &&
                !string.IsNullOrEmpty(t.lang) &&
                jaCodes.Contains(t.lang.ToLower()));

            var enAudio = tracks.FirstOrDefault(t =>
                t.type == "audio" &&
                !string.IsNullOrEmpty(t.lang) &&
                enCodes.Contains(t.lang.ToLower()));

            var jpAudio = tracks.FirstOrDefault(t =>
                t.type == "audio" &&
                !string.IsNullOrEmpty(t.lang) &&
                jaCodes.Contains(t.lang.ToLower()));

            // ----------------------------
            // ① 日本語字幕がある → 英語音声 + 日本語字幕
            // ----------------------------
            if (jpSub != null)
            {
                if (enAudio != null)
                {
                    _myplayer.SendToMpv(
                        $"{{\"command\": [\"set_property\", \"aid\", {enAudio.id}]}}");
                }

                _myplayer.SendToMpv(
                    $"{{\"command\": [\"set_property\", \"sid\", {jpSub.id}]}}");

                return;
            }

            // ----------------------------
            // ② 日本語字幕が無い → 日本語音声 + 字幕OFF
            // ----------------------------
            if (jpAudio != null)
            {
                _myplayer.SendToMpv(
                    $"{{\"command\": [\"set_property\", \"aid\", {jpAudio.id}]}}");

                _myplayer.SendToMpv(
                    "{\"command\": [\"set_property\", \"sid\", \"no\"]}");
            }
        }
        private void AutoSelectJapaneseAudioAndSubtitle(List<MpvTrack> tracks)
        {
            var jaCodes = new[] { "jpn", "ja", "jp", "japanese" };

            var jpAudio = tracks.FirstOrDefault(t =>
                t.type == "audio" &&
                !string.IsNullOrEmpty(t.lang) &&
                jaCodes.Contains(t.lang.ToLower()));

            var jpSub = tracks.FirstOrDefault(t =>
                t.type == "sub" &&
                !string.IsNullOrEmpty(t.lang) &&
                jaCodes.Contains(t.lang.ToLower()));

            if (jpAudio != null)
            {
                // 日本語音声
                _myplayer.SendToMpv($"{{\"command\": [\"set_property\", \"aid\", {jpAudio.id}]}}");

                // 字幕OFF
                _myplayer.SendToMpv("{\"command\": [\"set_property\", \"sid\", \"no\"]}");
            }
            else if (jpSub != null)
            {
                // 日本語字幕ON
                _myplayer.SendToMpv($"{{\"command\": [\"set_property\", \"sid\", {jpSub.id}]}}");
            }
        }
        public void panscan()
        {

            _myplayer.Video.panscan();
        }


        public string seiki_string_get(string text, String reg_st)
        {
            String re_text = "";
            try
            {
                System.Text.RegularExpressions.Regex Regex = new System.Text.RegularExpressions.Regex(reg_st, System.Text.RegularExpressions.RegexOptions.IgnoreCase);

                System.Text.RegularExpressions.Match Match = Regex.Match(text);


                while (Match.Success)
                {

                    re_text = Match.Groups[1].Value;



                    Match = Match.NextMatch();
                }
            }
            catch (System.Exception ex)
            {
                error.write_error_log(ex.Message + ex.StackTrace);
                Debug.WriteLine(ex.Message + ex.StackTrace);
            }
            return re_text;
        }
        private string FormatTime(double seconds)
        {
            var ts = System.TimeSpan.FromSeconds(seconds);
            return ts.ToString(@"h\:mm\:ss");
        }
        private void UpdateTimeLabel()
        {
            BeginInvoke(() =>
            {
                lblTime.Text =
                    $"{FormatTime(_timePos)} / {FormatTime(_duration)}";
            });
        }
        private string FormatFileSize(double bytes)
        {
            if (bytes == 0)
            {
                return "";
            }
            if (bytes <10000)
            {
                return "";
            }
          
            const double GB = 1024 * 1024 * 1024;
            const double MB = 1024 * 1024;
           
            if (bytes >= GB)
            {
                double g = bytes / GB;
                return $"{g:F1}G";
            }
            else
            {
                double m = bytes / MB;
                if (m == 0)
                {
                    return"";
                }
                return $"{m:F0}M";
            }
        }
        private void UpdateResolutionLabel()
        {

            String size_st = FormatFileSize(_filesize);
            BeginInvoke(() =>
            {
                if (_filesize > 0)
                {
                    lblFilesize.Text = $"{size_st} ";
                }
                lblResolution.Text = $"{_videoWidth} x {_videoHeight}";
            });
        }

        private async void open_func()
        {

            using OpenFileDialog ofd = new OpenFileDialog();
            ofd.Filter = "Video Files|*.mp4;*.iso;*.mkv;*.avi;*.mov|All Files|*.*";
            if (ofd.ShowDialog() == DialogResult.OK)
                StartMpv(ofd.FileName);
            currentFilePath = ofd.FileName;
            start_list_update(currentFilePath);

        }


        public async void open_folder_func()
        {

            FolderBrowserDialog dialog = new FolderBrowserDialog();

            dialog.Description = "フォルダを選択してください";

            if (dialog.ShowDialog() == DialogResult.OK)
            {
                string folderPath = dialog.SelectedPath;
                
                await Task.Run(() => folder_get(folderPath));
                if (config_class.config_int_read("起動時のリスト") == 1)
                {
                    list_folder();
                }
            }
        }

        public void ApplyGlsl(String glsl_path)
        {

            _myplayer.Video.ApplyGlsl(glsl_path);

        }
        public void vf_normal()
        {

            _myplayer.Video.vf_normal();
        }
        public void video_flip()
        {

            _myplayer.Video.video_flip();
        }
        public void video_rotate_90_right()
        {

            _myplayer.Video.video_rotate_90_right();
        }
        public void video_rotate_90_left()
        {

            _myplayer.Video.video_rotate_90_left();
        }
        public void audio_lavfi_normal()
        {
            _myplayer.Audio.audio_lavfi_normal();
        }

        public void audio_lavfi(String name)
        {
            _myplayer.Audio.audio_lavfi(name);

        }
        public void audio_lavfi_single(String name)
        {
            _myplayer.Audio.audio_lavfi_single(name);

        }


        public void video_lavfi(String name)
        {

            _myplayer.Video.video_lavfi(name);
        }

        public void Video_Preset(String name)
        {

            _myplayer.Video.ApplyPreset(name);
        }
        public void Audio_Preset(String name)
        {

            _myplayer.Audio.ApplyEqPreset(name);
        }

        //public void list_arva()
        //{
        //    list_change("arva", arva_lists);


        //}
        public void list_cat_music()
        {
            list_change("音楽", cat_url.music_urls);


        }
        public void webview2_kill()
        {
            StopMpv();
            try
            {
                Process[] ps = Process.GetProcessesByName("msedgewebview2");
                foreach (Process item in ps)
                {

                    item.Kill();
                    item.Close();
                    item.Dispose();
                }

            }
            catch (System.Exception ex)
            {
                Debug.WriteLine(ex.Message + ex.StackTrace);

            }
            
            foreach (var p in Process.GetProcessesByName("msedgewebview2"))
            {
                p.Kill();
            }


        }
        public void list_cat_news()
        {
            list_change("ニュース", cat_url.news_urls);


        }
        public void list_cat_gamble()
        {
            list_change("ギャンブル", cat_url.gamble_urls);


        }
        public void list_cat_hobby()
        {
            list_change("趣味", cat_url.hobby_urls);


        }
        public void list_cat_bs()
        {
            list_change("BS無料", cat_url.bs_urls);


        }
        public void list_cat_movie()
        {
            list_change("映画", cat_url.movie_urls);


        }
        public void list_cat_culture()
        {
            list_change("教養", cat_url.culture_urls);


        }
        public void list_cat_sports()
        {
            list_change("スポーツ", cat_url.sports_urls);


        }
        public void list_cat_anime()
        {
            list_change("アニメ", cat_url.anime_urls);

        }
        public void list_cat_tv()
        {
            list_change("地上波TV", cat_url.tv_urls);

        }
        public void list_cat_kansai()
        {
            list_change("関西", cat_url.kansai_urls);

        }
        public void list_rakuten()
        {
            list_change("楽天", rakuten_lists);


        }
        public void video_aspect(String value)
        {
            _myplayer.Video.aspect(value);
        }

        public void panscan_normal()
        {

            _myplayer.Video.panscan_normal();
        }
        public void list_db()
        {
            list_change("動画DB", db_all_video_lists);





        }




        private async void start_list_update(String path)
        {
         
            if (config_class.config_bool_read("再生時にフォルダの動画をリストに入れる") == true)
            {
            
                await Task.Run(() => folder_get_movie(path));
            }


            if (config_class.config_int_read("起動時のリスト") == 1)
            {
                list_folder();
            }

        }


        string GetFileSize(string path)
        {

            if (System.Text.RegularExpressions.Regex.IsMatch(path, "https?:", System.Text.RegularExpressions.RegexOptions.IgnoreCase))
            {
                return "";
            }
            if (System.IO.File.Exists(path) == false)
            {
                return "";
            }
            long size = new FileInfo(path).Length;
         
            if (size == 0)
            {
                return "";

            }
            return $"{size / 1024 / 1024} MB";
        }

        public void BtnOpen_Click(object sender, EventArgs e)
        {
            open_func();

        }
    }
}