ネット上で調べても解決策が発見できなかったため、知恵をお借り出来たらと思い、質問させていただきました。
ku__ra__geさんも指摘されていますが、質問のリンクの前(上?)のページにあります。
iframe 組み込みの YouTube Player API リファレンス - 動画の再生 | YouTube IFrame Player API
iframe 組み込みの YouTube Player API リファレンス - プレーヤーの音量の変更 | YouTube IFrame Player API
実装方法に心当たりがありましたら、ご協力お願いいたします。
特に心当たりはありませんが、ちょっと面白そうなのでやってみました。
なんでもいいということですので、WebView2
を使用しました(CefSharp
は以前苦戦して苦手意識がある^^;
WinForms アプリでの WebView2 の使用を開始する - Microsoft Edge Development | Microsoft Docs
cs
1 using System ;
2 using System . Diagnostics ;
3 using System . IO ;
4 using System . Windows . Forms ;
5 using Microsoft . Web . WebView2 . Core ;
6
7 namespace Questions370144
8 {
9 public partial class Form1 : Form
10 {
11 private bool playing ;
12 private bool seeking ;
13
14 public Form1 ( )
15 {
16 InitializeComponent ( ) ;
17 InitializeAsync ( ) ;
18 }
19
20 private async void InitializeAsync ( )
21 {
22 await webView21 . EnsureCoreWebView2Async ( null ) ;
23
24 webView21 . CoreWebView2 . WebMessageReceived += CoreWebView2_WebMessageReceived ;
25
26 var html = Path . Combine ( AppDomain . CurrentDomain . BaseDirectory , "index.html" ) ;
27 webView21 . CoreWebView2 . Navigate ( new Uri ( html ) . AbsoluteUri ) ;
28 }
29
30 private void CoreWebView2_WebMessageReceived ( object sender , CoreWebView2WebMessageReceivedEventArgs e )
31 {
32 var str = e . TryGetWebMessageAsString ( ) ;
33 Debug . WriteLine ( str ) ;
34
35 switch ( str . Split ( ',' ) [ 0 ] )
36 {
37 case "UNSTARTED" :
38 progressBar1 . Value = 0 ;
39 progressBar1 . Maximum = int . Parse ( str . Split ( ',' ) [ 1 ] ) ;
40 break ;
41 case "ENDED" :
42 timer1 . Stop ( ) ;
43 playing = false ;
44 break ;
45 case "PLAYING" :
46 timer1 . Start ( ) ;
47 playing = true ;
48 break ;
49 case "PAUSED" :
50 timer1 . Stop ( ) ;
51 playing = false ;
52 break ;
53 case "BUFFERING" : break ;
54 //case "CUED": break;
55 }
56 }
57
58 private void button1_Click ( object sender , EventArgs e )
59 {
60 webView21 . CoreWebView2 . ExecuteScriptAsync ( $"playVideo()" ) ;
61 }
62
63 private void button2_Click ( object sender , EventArgs e )
64 {
65 webView21 . CoreWebView2 . ExecuteScriptAsync ( $"pauseVideo()" ) ;
66 }
67
68 private void trackBar1_Scroll ( object sender , EventArgs e )
69 {
70 webView21 . CoreWebView2 . ExecuteScriptAsync ( $"setVolume( { trackBar1 . Value } )" ) ;
71 }
72
73 private void checkBox1_CheckedChanged ( object sender , EventArgs e )
74 {
75 if ( checkBox1 . Checked )
76 {
77 checkBox1 . Text = "🔇" ;
78 webView21 . CoreWebView2 . ExecuteScriptAsync ( $"mute()" ) ;
79 }
80 else
81 {
82 checkBox1 . Text = "🔊" ;
83 webView21 . CoreWebView2 . ExecuteScriptAsync ( $"unMute()" ) ;
84 }
85 }
86
87 private void progressBar1_MouseDown ( object sender , MouseEventArgs e )
88 {
89 seeking = true ;
90 timer1 . Stop ( ) ;
91
92 var value = ( int ) ( e . X / ( double ) progressBar1 . Width * progressBar1 . Maximum ) ;
93 progressBar1 . Value = value ;
94 webView21 . CoreWebView2 . ExecuteScriptAsync ( $"seekTo( { value } , false)" ) ;
95 }
96
97 private void progressBar1_MouseUp ( object sender , MouseEventArgs e )
98 {
99 seeking = false ;
100 if ( playing ) timer1 . Start ( ) ;
101
102 var value = ( int ) ( e . X / ( double ) progressBar1 . Width * progressBar1 . Maximum ) ;
103 progressBar1 . Value = value ;
104 webView21 . CoreWebView2 . ExecuteScriptAsync ( $"seekTo( { value } , true)" ) ;
105 }
106
107 private void progressBar1_MouseMove ( object sender , MouseEventArgs e )
108 {
109 if ( seeking )
110 {
111 var value = ( int ) ( e . X / ( double ) progressBar1 . Width * progressBar1 . Maximum ) ;
112 progressBar1 . Value = value ;
113 webView21 . CoreWebView2 . ExecuteScriptAsync ( $"seekTo( { value } , false)" ) ;
114 }
115 }
116
117 private async void timer1_Tick ( object sender , EventArgs e )
118 {
119 var str = await webView21 . CoreWebView2 . ExecuteScriptAsync ( $"getCurrentTime()" ) ;
120 Debug . WriteLine ( str ) ;
121
122 if ( double . TryParse ( str . Trim ( '"' ) , out var value ) ) progressBar1 . Value = ( int ) value ;
123 }
124 }
125 }
Form1.Designer.csまで入れると、1万字を超えてしまうので省略します。
以下のコントロールがあるとする(イベントも適宜設定のこと)
WebView2 webView21
Button button1(再生ボタン)
Button button2(ポーズボタン)
CheckBox checkBox1(ミュートトグルボタン)
TrackBar trackBar1(音量)
ProgressBar progressBar1(シークバー)
Timer timer1(シークバーを進めるタイマ)
html:index.html
1 <! DOCTYPE html >
2 < html >
3 < body >
4 < div id = " player " > </ div >
5
6 < script >
7 var tag = document . createElement ( 'script' ) ;
8
9 tag . src = "https://www.youtube.com/iframe_api" ;
10 var firstScriptTag = document . getElementsByTagName ( 'script' ) [ 0 ] ;
11 firstScriptTag . parentNode . insertBefore ( tag , firstScriptTag ) ;
12
13 var player ;
14 function onYouTubeIframeAPIReady ( ) {
15 player = new YT . Player ( 'player' , {
16 height : '360' ,
17 width : '640' ,
18 videoId : 'M7lc1UVf-VE' ,
19 playerVars : { controls : 0 } ,
20 events : {
21 'onReady' : onPlayerReady ,
22 'onStateChange' : onPlayerStateChange
23 }
24 } ) ;
25 }
26
27 function onPlayerReady ( event ) {
28 event . target . playVideo ( ) ;
29 }
30
31 function onPlayerStateChange ( event ) {
32 if ( event . data == YT . PlayerState . UNSTARTED ) {
33 chrome . webview . postMessage ( 'UNSTARTED,' + player . getDuration ( ) . toString ( ) ) ;
34 } else if ( event . data == YT . PlayerState . ENDED ) {
35 chrome . webview . postMessage ( 'ENDED' ) ;
36 } else if ( event . data == YT . PlayerState . PLAYING ) {
37 chrome . webview . postMessage ( 'PLAYING' ) ;
38 } else if ( event . data == YT . PlayerState . PAUSED ) {
39 chrome . webview . postMessage ( 'PAUSED' ) ;
40 } else if ( event . data == YT . PlayerState . BUFFERING ) {
41 chrome . webview . postMessage ( 'BUFFERING' ) ;
42 //} else if (event.data == YT.PlayerState.CUED) { // これいつ来るんだろう?
43 //chrome.webview.postMessage('CUED,' + player.getDuration().toString());
44 } else {
45 chrome . webview . postMessage ( event . data . toString ( ) ) ;
46 }
47 }
48
49 //function loadVideoById(videoId) { player.loadVideoById(videoId); } // loadVideoByIdはイベントが来ずいきなり再生される
50 function cueVideoById ( videoId ) { player . cueVideoById ( videoId ) ; } // こっちのほうがいい
51 function playVideo ( ) { player . playVideo ( ) ; }
52 function pauseVideo ( ) { player . pauseVideo ( ) ; }
53 function stopVideo ( ) { player . stopVideo ( ) ; }
54 function setVolume ( volume ) { player . setVolume ( volume ) ; } // 0~100 の整数値
55 function mute ( ) { player . mute ( ) ; }
56 function unMute ( ) { player . unMute ( ) ; }
57 function getPlayerState ( ) { return player . getPlayerState ( ) . toString ( ) ; }
58 function getCurrentTime ( ) { return player . getCurrentTime ( ) . toString ( ) ; }
59 function seekTo ( seconds , allowSeekAhead ) { player . seekTo ( seconds , allowSeekAhead ) ; }
60 </ script >
61 </ body >
62 </ html >
一応ひと通りの操作はできましたが、確認は雑なので何かエラーが出るかもしれません。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/11/20 01:27
2021/11/20 18:45