Playing with Youtube medias (video-audio)

Published on by Yousfi Benameur


The JavaScript API allows users to control embedded YouTube video players  via JavaScript.
youtube video can be embed in an iframe with all parameters needed.
 < iframe class="youtube-player" id="player" type="text/html" src="http://www.youtube.com/embed/JW5meKfy3fY?wmode=opaque&autohide=1&autoplay=1&enablejsapi=1" frameborder="0"><br /></iframe >
that is suffisent to play youtube video with custom parameters.
this code embeds on a top level form a vfp IE browser with a player configured with javascript.

Functions can be called to play a video, pause it, reach certain passages, adjust the volume, mute the  sound and use other useful features.
The best refrence for that is here:https://developers.google.com/youtube/js_api_reference?csw=1
this work is adapted from this tutoriel:http://demo.tutorialzine.com/2015/08/how-to-control-youtubes-video-player-with-javascript/
can gather some youtube video IDs in a cursor  and build easily a playlist as we show on youtube.
the left pannel menu of the player is the playlist.Its scrollable.
if the url captured from any youtube video (right click on and grab url) is for ex: http://youtube-be/Xa0Q0J5tOP0
the videoID is:Xa0Q0J5tOP0 that is what compose the cursor ycurs created(otherwise get errors and video dont play).All libraries links are from the web.
All the code is of course javascript overlapped by VFP as builder.
Note: can create a project, add this prg and a config.fpw & compile an executable.
this works fine under condition you register exe it as IE11/Edge emulation (otherwise it dont works).this is available for any exe working with ie browser.
see: http://yousfi.over-blog.com/2015/01/who-said-that-vfp-ie-browser-died.html
code *1* and *2*.

[Post 226]


Click on code to select [then copy] -click outside to deselect

*1* created on 20 of march 2017
*building a youtube player with  playlist of media (video,audio)

publi yform
yform=newObject("youtube")
yform.show
read events

DEFINE CLASS youtube AS form
Height = 539
Width = 946
ShowWindow = 2
ShowTips = .T.
AutoCenter = .T.
Caption = "Youtube PlayList"
Name = "Form1"

ADD OBJECT olecontrol1 AS olecontrol WITH ;
Oleclass="shell.explorer.2",;
Top = 14, ;
Left = 0, ;
Height = 528, ;
Width = 948, ;
Anchor = 15, ;
Name = "Olecontrol1"

ADD OBJECT shape1 AS shape WITH ;
Top = 0, ;
Left = 890, ;
Height = 13, ;
Width = 13, ;
Anchor = 768, ;
Curvature = 99, ;
MousePointer = 15, ;
ToolTipText = "Titlebar on/off", ;
SpecialEffect = 0, ;
BackColor = RGB(255,0,0), ;
Name = "Shape1"

ADD OBJECT  yhelp AS shape with ;
Top = 0,;
Left = 922,;
Height = 13,;
Width = 13,;
Anchor = 768,;
Curvature = 99,;
MousePointer = 15,;
ToolTipText = "Summary Help",;
SpecialEffect = 0,;
BackColor = RGB(0,255,0),;
Name = "yhelp"


PROCEDURE yhelp.Click
local m.myvar
text to m.myvar pretext 7 noshow
The JavaScript API allows users to control embedded YouTube video players and Chromeless via JavaScript.
youtube video can be embed in an iframe with all parameters needed.

< iframe class="youtube-player" id="player" type="text/html" src="http://www.youtube.com/embed/JW5meKfy3fY?wmode=opaque&autohide=1&autoplay=1&enablejsapi=1" frameborder="0" ><br />< / iframe >

that is suffisent to play youtube video with custom parameters.
this code embed on a top level form a vfp IE browser with a player configured with javascript.

Functions can be called to play a video, pause it, reach certain passages, adjust the volume, mute the
sound and use other useful features.
The best refrence for that is here:https://developers.google.com/youtube/js_api_reference?csw=1
this work is adapted from this tutoriel:http://demo.tutorialzine.com/2015/08/how-to-control-youtubes-video-player-with-javascript/
can gather some youtube video IDs in a cursor  and build easily a playlist as we show on youtube.
the left pannel menu of the player is the playlist (here 10 youtub videos with their IDs only no less no more).
if the url captured from any youtube video (right click on and grab url) is for ex: http://youtube-be/Xa0Q0J5tOP0
the videoID is:Xa0Q0J5tOP0 that is what compose the cursor ycurs created(otherwise get errors and video dont play).
All the code is of course javascript overlapped by VFP as builder.
the youtube video resizes with the form,can show/hide form titlebar.
Of course all the video controls are in the video area.
this desserves  also for any youtube audio.
the html file (captured in temp folder) can be exported as static file for ex to a presentation,...(comment the line in form
destroy event for this purpose.)
endtext
*messagebox(m.myvar,0+32+4096,"Summary help")

_cliptext=m.myvar
#define MB_ICONINFORMATION 0x00000040
#define MB_OK 0x00000000
#define MB_APPLMODAL 0x00000000
#define  MB_DEFBUTTON1 0x00000000

DECLARE INTEGER MessageBox IN user32 As MessageBoxA;
INTEGER hwnd,;
STRING  lpText,;
STRING  lpCaption,;
INTEGER wType

*buttons
#define MB_ABORTRETRYIGNORE 0x00000002
#define MB_CANCELTRYCONTINUE 0x00000006
#define MB_HELP 0x00004000

#define MB_OKCANCEL 0x00000001
#define MB_RETRYCANCEL 0x00000005
#define MB_YESNO  0x00000004
#define MB_YESNOCANCEL 0x00000003

*Icons
#define  MB_ICONEXCLAMATION 0x00000030
#define MB_ICONWARNING 0x00000030

#define MB_ICONASTERISK 0x00000040
#define MB_ICONQUESTION 0x00000020
#define MB_ICONSTOP 0x00000010
#define MB_ICONERROR 0x00000010
#define MB_ICONHAND  0x00000010

*To indicate the default button, specify one of the following values.

#define MB_DEFBUTTON2 0x00000100
#define MB_DEFBUTTON3 0x00000200
#define MB_DEFBUTTON4 0x00000300

*To indicate the modality of the dialog box, specify one of the following values.

#define MB_SYSTEMMODAL 0x00001000
#define MB_TASKMODAL 0x00002000

*To specify other options, use one or more of the following values.
#define MB_DEFAULT_DESKTOP_ONLY 0x00020000
#define MB_RIGHT 0x00080000
#define MB_RTLREADING  0x00100000
#define MB_SETFOREGROUND  0x00010000
#define MB_TOPMOST  0x00040000
#define MB_SERVICE_NOTIFICATION 0x00200000

*Return code
#define IDABORT 3
#define IDCANCEL 2
#define IDCONTINUE 11
#define IDIGNORE 5
#define IDNO 7
#define IDOK 1
#define IDRETRY 4
#define IDTRYAGAIN 10
#define IDYES 6
MessageBoxA(_vfp.hwnd,m.myvar,"Summary help (text in clipboard)",MB_APPLMODAL+MB_OK +MB_ICONINFORMATION +MB_DEFBUTTON1 )
ENDPROC

PROCEDURE ybuild
sele ycurs
locate
local pl1,pl
pl1=allt(xmedia)
pl=""
scan for recno()>1
pl=pl+allt(xmedia)+iif(recno()<reccount(),",","")
endscan

local m.myvar,m.xx
text to m.xx textmerge noshow
<script>
var player,
time_update_interval = 0;

function onYouTubeIframeAPIReady() {
player = new YT.Player('video-placeholder', {
width: <<thisform.width>>,
height: <<thisform.height-14>>,
videoId: '<<m.pl1>>',
playerVars: {
	color: 'white',
	enablejsapi:1,
	frameborder:0 ,
	allowfullscreen:1,
	autoplay:1,
	rel:0,	
	playlist: '<<m.pl>>'
},
events: {
	onReady: initialize
}
});
}

function initialize(){

// Update the controls on load
updateTimerDisplay();
updateProgressBar();

// Clear any old interval.
clearInterval(time_update_interval);

// Start interval to update elapsed time display and
// the elapsed part of the progress bar every second.
time_update_interval = setInterval(function () {
updateTimerDisplay();
updateProgressBar();
}, 1000);

$('#volume-input').val(Math.round(player.getVolume()));
}

// This function is called by initialize()
function updateTimerDisplay(){
// Update current time text display.
$('#current-time').text(formatTime( player.getCurrentTime() ));
$('#duration').text(formatTime( player.getDuration() ));
}

// This function is called by initialize()
function updateProgressBar(){
// Update the value of our progress bar accordingly.
$('#progress-bar').val((player.getCurrentTime() / player.getDuration()) * 100);
}

// Progress bar
$('#progress-bar').on('mouseup touchend', function (e) {

// Calculate the new time for the video.
// new time in seconds = total duration in seconds * ( value of range input / 100 )
var newTime = player.getDuration() * (e.target.value / 100);

// Skip video to new time.
player.seekTo(newTime);

});

// Playback

$('#play').on('click', function () {
player.playVideo();
});


$('#pause').on('click', function () {
player.pauseVideo();
});

// Sound volume

$('#mute-toggle').on('click', function() {
var mute_toggle = $(this);

if(player.isMuted()){
player.unMute();
mute_toggle.text('volume_up');
}
else{
player.mute();
mute_toggle.text('volume_off');
}
});

$('#volume-input').on('change', function () {
player.setVolume($(this).val());
});

// Other options

$('#speed').on('change', function () {
player.setPlaybackRate($(this).val());
});

$('#quality').on('change', function () {
player.setPlaybackQuality($(this).val());
});

// Playlist

$('#next').on('click', function () {
player.nextVideo()
});

$('#prev').on('click', function () {
player.previousVideo()
});

// Load video

$('.thumbnail').on('click', function () {

var url = $(this).attr('data-video-id');

player.cueVideoById(url);

});

// Helper Functions

function formatTime(time){
time = Math.round(time);

var minutes = Math.floor(time / 60),
seconds = time - minutes * 60;

seconds = seconds < 10 ? '0' + seconds : seconds;

return minutes + ":" + seconds;
}

$('pre code').each(function(i, block) {
hljs.highlightBlock(block);
});
</script>
endtext

text to m.myvar textmerge noshow
<!DOCTYPE html>
<html>

<head lang="en">
<meta charset="UTF-8">
<title>How to Control YouTube's Video Player with JavaScript</title>
<link rel="stylesheet" href="http://demo.tutorialzine.com/2015/08/how-to-control-youtubes-video-player-with-javascript/demo.css" type="text/css">
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">

<link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.6/styles/default.min.css">
<link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.6/styles/tomorrow.min.css">

</head>

<body bgcolor=black scroll="no">
<!-- 1. The <iframe> (and video player) will replace this <div> tag. -->
<div id="video-placeholder"></div>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.6/highlight.min.js"></script>
<script src="https://www.youtube.com/iframe_api"></script>

<<m.xx>>

</body>
</html>
endtext
local m.lcdest
m.lcdest=addbs(sys(2023))+"ytemp.html"
strtofile(m.myvar,m.lcdest)
thisform.olecontrol1.navigate(m.lcdest)
thisform.backcolor=0
ENDPROC

PROCEDURE Destroy
erase addbs(sys(2023))+"ytemp.html
clea events
ENDPROC

PROCEDURE Load
_screen.windowstate=1
set safe off
*build your playlist with youtube videoIds here
create cursor ycurs (xmedia c(150))
insert into ycurs values("Xa0Q0J5tOP0")
insert into ycurs values("INLzqh7rZ-U")
insert into ycurs values("0Bmhjf0rKe8")
insert into ycurs values("Gs8lACWtL-A")
insert into ycurs values("YfKfU8rQGKA")
insert into ycurs values("JtHrsXEa7d4")
insert into ycurs values("M6p1_9MR5PQ")
insert into ycurs values("gwinFP8_qIM")
insert into ycurs values("-_9BYSDtwRc")
insert into ycurs values("JpNg8Z75sEs")
ENDPROC

PROCEDURE Init
sele ycurs
thisform.caption=thisform.caption+"["+trans(reccount())+" item(s)]"
thisform.ybuild()
ENDPROC

PROCEDURE Resize
thisform.olecontrol1.resize()
ENDPROC

PROCEDURE olecontrol1.Init
this.silent=.t.
ENDPROC

PROCEDURE olecontrol1.Resize
*the youtube video fills the form area
try
with thisform.olecontrol1.document.getElementById("video-placeholder")
.width=thisform.width
.height=thisform.height-14
endwith
catch
endtry
ENDPROC

PROCEDURE shape1.Click
with thisform
.titlebar=iif(.titlebar=1,0,1)
do case
case .titlebar=0
.height=.height+sysmetric(9)+sysmetric(4)
case .titlebar=0
.heght=.height-sysmetric(9)-sysmetric(4)
endcase
endwith
ENDPROC

ENDDEFINE
*
*-- EndDefine: youtube


www.google.com--youtube account----pick some youtube videoIds and fill the cursor...run the form.
www.google.com--youtube account----pick some youtube videoIds and fill the cursor...run the form.
www.google.com--youtube account----pick some youtube videoIds and fill the cursor...run the form.
www.google.com--youtube account----pick some youtube videoIds and fill the cursor...run the form.
www.google.com--youtube account----pick some youtube videoIds and fill the cursor...run the form.

www.google.com--youtube account----pick some youtube videoIds and fill the cursor...run the form.

Click on code to select [then copy] -click outside to deselect


*2*created on 21 of march 2017
*!*	a basic youtube video/audio player built with www.youtube.com/player_api (linked by internet of course).
*!*	can play with the form max button and the player fullscreen control to expand the video (on a form fullscreen is limited to form area)

publi yform
yform=newObject("youtube_player")
yform.show
read events
retu
*
DEFINE CLASS youtube_player AS form
	BorderStyle = 0
	Height = 452
	Width = 861
	ShowWindow = 2
	AutoCenter = .T.
	Caption = "Youtube player prototype"
	Name = "Form1"

	ADD OBJECT olecontrol1 AS olecontrol WITH ;
	   Oleclass="shell.explorer.2", ;
		Top = 0, ;
		Left = 0, ;
		Height = 457, ;
		Width = 865, ;
		Anchor = 15, ;
		Name = "Olecontrol1"

	PROCEDURE ybuild
		Lparameters xmedia
		Local m.myvar
		TEXT to m.myvar textmerge noshow
		<body scroll="no"
		<div id="ytplayer"></div>

		<script>
		  // Load the IFrame Player API code asynchronously.
		  var tag = document.createElement('script');
		  tag.src = "https://www.youtube.com/player_api";
		  var firstScriptTag = document.getElementsByTagName('script')[0];
		  firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
		  // Replace the 'ytplayer' element with an <iframe> and
		  // YouTube player after the API code downloads.
		  var player;
		  function onYouTubePlayerAPIReady() {
		    player = new YT.Player('ytplayer', {
		
		      width: '<<thisform.width>>',
	height:'<<thisform.height>>',		
		      playerVars: {autoplay:1, loop:0,autoplay:1,rel:0,enablejsapi:1,frameborder:0 ,allowfullscreen:1},			
		      videoId: '<<xmedia>>'
		    });
		  }
		</script>
		ENDTEXT
	
		Local m.lcdest
		m.lcdest=Addbs(Sys(2023))+"ytemp.html"
		Strtofile(m.myvar,m.lcdest)
		Thisform.olecontrol1.Navigate(m.lcdest)
		Thisform.Caption="Youtube player prototype "+"[playing :"+Allt(xmedia)+"]"
	ENDPROC

	PROCEDURE Init
		set safe off
    _screen.windowstate=1
	thisform.ybuild("M7lc1UVf-VE")     &&any youtube videoID here a youtube tutoriel
	ENDPROC

	PROCEDURE Destroy
		erase addbs(sys(2023))+"ytemp.html"  &&can comment to see the page built
		clea events
	ENDPROC

	PROCEDURE olecontrol1.Init
	this.silent=.t.
	ENDPROC

ENDDEFINE
*
*-- EndDefine: youtube_player


it seems autoplay=1 dont work on this video (solved with playerVars statement).

it seems autoplay=1 dont work on this video (solved with playerVars statement).

Click on code to select [then copy] -click outside to deselect


*3* created on 23 of march 2017
*this code builds a customized list of youtube videos as web links and show each one in a lightbox effect.
*click anywhere to close the video
*sometimes for slow internet connection, the entiere page can be load(alt+left arrow to navigue home) !
*code adapted from tutoriel http://www.javascriptkit.com/dhtmltutors/youtube-api-lightbox3.shtml

publi yform
yform=newObject("ytlightbox")
yform.show
read events
retu

DEFINE CLASS ytlightbox AS form
	Height = 571
	Width = 946
	ShowWindow = 2
	AutoCenter = .T.
	Caption = "Youtube video with Lightbox style---Click on one of the sample links below to launch a Youtube video inside lightbox:"
	BackColor = RGB(0,0,0)
	Name = "Form1"

	ADD OBJECT olecontrol1 AS olecontrol WITH ;
        oleclass="shell.explorer.2",;
		Top = 0, ;
		Left = 0, ;
		Height = 577, ;
		Width = 949, ;
		Anchor = 15, ;
		Name = "Olecontrol1"

	PROCEDURE ybuild
		local m.xlist
		sele ycurs
		m.xlist="<ul><br/>"+chr(13)
		scan
		m.xlist=m.xlist+[<li><a href="]+allt(xmedia)+[" class="lightbox">Video]+trans(recno())+[</a></li>]+chr(13)
		endscan
		m.xlist=m.xlist+"<br/></ul>"+chr(13)

		local m.myvar
		text to m.myvar textmerge noshow
		<!-- adapted form :http://www.javascriptkit.com/dhtmltutors/youtube-api-lightbox3.shtml-->
		<!doctype html>
		<head>

		<style>
		/* Parent element can be any width and height */
		.parent{
			position: fixed;
			width: 100%; /* can be any width */
			height: 100%;
			left: 0;
			top: 0;
			display: none;
			text-align: center;
		}

		.parent:before{ /* pseudo element to force vertical centering of child element */
			content: '';
			display: inline-block;
			height: 100%;
			vertical-align: middle;
		}

		.parent:after{ /* pseudo element to create overlay */
			background: black;
			content: '';
			position: absolute;
			width: 100%;
			height: 100%;
			top: 0;
			left: 0;
			opacity: 0.5;
			z-index: 10;
		}

		/* Centered child element can be any width and height */
		.centeredchild{
			position: relative; /* position element to participate in z-indexing */
			z-index: 20; /* higher z-index than overlay */
			display: inline-block;
			vertical-align: middle;
			width: 80%; /* can be any width */
		}

		/* Video container to maintain Youtube 16:9 aspect ratio */
		.videowrapper{
			position: relative;
			padding-top: 25px;
			padding-bottom: 56.25%; /* 16:9 aspect ratio */
			height: 0;
		}

		/* Make Youtube IFRAME responsive */
		.videowrapper iframe {
			position: absolute;
			top: 0;
			left: 0;
			width: 100%;
			height: 100%;
		}
		ul{background-color:gold;border:solid 2px maroon;width:250px;padding;15px;}
		.myH1 {color:maroon;font-size:20px;text-shadow:5px 5px 10px red;font-bold:bold;}
		</style>
		<meta name="viewport" content="width=device-width, initial-scale=1">
		</head>
		<body oncontextmenu="return false;" scroll="no" bgcolor=bisque>
		<h2 class="myH1">Click on one of the sample links below to launch a Youtube video inside lightbox: </h2>
		<<m.xlist>>
		<div id="youtubelightbox" class="parent">
			<div class="centeredchild">
				<div class="videowrapper">
				<div id="playerdiv"></div>
				</div>
			</div>
		</div>
		<!-- Add this to bottom of page after the lightbox markup-->
		<script>

		// load Youtube API code asynchronously
		var tag = document.createElement('script')

		tag.src = "https://www.youtube.com/iframe_api";
		var firstScriptTag = document.getElementsByTagName('script')[0]
		firstScriptTag.parentNode.insertBefore(tag, firstScriptTag)

		var isiOS = navigator.userAgent.match(/(iPad)|(iPhone)|(iPod)/i) != null //boolean check for iOS devices

		var youtubelightbox = document.getElementById('youtubelightbox')
		var player // variable to hold new YT.Player() instance

		// Hide lightbox when clicked on
		youtubelightbox.addEventListener('click', function(){
			this.style.display = 'none'
			player.stopVideo()
		}, false)

		// Exclude youtube iframe from above action
		youtubelightbox.querySelector('.centeredchild').addEventListener('click', function(e){
			e.stopPropagation()
		}, false)


		// define onYouTubeIframeAPIReady() function and initialize lightbox when API is ready
		function onYouTubeIframeAPIReady() {
			createlightbox()
		}
		// Extracts the Youtube video ID from a well formed Youtube URL
		function getyoutubeid(link){
			// Assumed Youtube URL formats
			// https://www.youtube.com/watch?v=Pe0jFDPHkzo
			// https://youtu.be/Pe0jFDPHkzo
			// https://www.youtube.com/v/Pe0jFDPHkzo
			// and more

			//See http://stackoverflow.com/a/6904504/4360074
			var youtubeidreg = /(?:youtube\.com\/(?:[^\/]+\/.+\/|(?:v|e(?:mbed)?)\/|.*[?&]v=)|youtu\.be\/)([^"&?\/ ]{11})/i;
			return youtubeidreg.exec(link)[1] // return Youtube video ID portion of link
		}
		// Creates a new YT.Player() instance
		function createyoutubeplayer(videourl){
			player = new YT.Player('playerdiv', {
				videoId: videourl,
				playerVars: {autoplay:1}
			})
		}
		// Main Youtube lightbox function
		function createlightbox(){
			var targetlinks = document.querySelectorAll('.lightbox')
			for (var i=0; i<targetlinks.length; i++){
				var link = targetlinks[i]
				link._videoid = getyoutubeid(link) // store youtube video ID portion of link inside _videoid property
				targetlinks[i].addEventListener('click', function(e){
					youtubelightbox.style.display = 'block'
					if (typeof player == 'undefined'){ // if video player hasn't been created yet
						createyoutubeplayer(this._videoid)
					}
					else{
						if (isiOS){ // iOS devices can only use the "cue" related methods
							player.cueVideoById(this._videoid)
						}
						else{
							player.loadVideoById(this._videoid)
						}
					}
					e.preventDefault()
				}, false)
			}
		}
		</script>
		</body>
		</html>
		endtext

		local m.lcdest
		m.lcdest=addbs(sys(2023))+"ytemp.html"
		strtofile(m.myvar,m.lcdest)
		thisform.olecontrol1.navigate(m.lcdest)
	ENDPROC

	PROCEDURE Activate
		thisform.windowstate=2
		this.caption=this.caption
	ENDPROC


	PROCEDURE Destroy
		erase addbs(sys(2023))+"ytemp.html"   &&clean (can uncoment to see the result code)
		clea events
	ENDPROC

	PROCEDURE Init
		thisform.ybuild()
	ENDPROC

	PROCEDURE Load
		close data all
		set safe off
		create cursor ycurs (xmedia c(150))
		insert into ycurs values("https://www.youtube.com/watch?v=Pe0jFDPHkzo")
		insert into ycurs values("https://youtu.be/oIlIVFBBbNw")
		insert into ycurs values("https://www.youtube.com/watch?v=fzrfrXhE-w4")
		insert into ycurs values("https://youtube.com/watch?v=Xa0Q0J5tOP0")
		insert into ycurs values("https://youtube.com/watch?v=INLzqh7rZ-U")
		insert into ycurs values("https://youtube.com/watch?v=0Bmhjf0rKe8")
		insert into ycurs values("https://youtube.com/watch?v=Gs8lACWtL-A")
		insert into ycurs values("https://youtube.com/watch?v=YfKfU8rQGKA")
		insert into ycurs values("https://youtube.com/watch?v=JtHrsXEa7d4")
		insert into ycurs values("https://youtube.com/watch?v=M6p1_9MR5PQ")
		insert into ycurs values("https://youtube.com/watch?v=gwinFP8_qIM")
		insert into ycurs values("https://youtube.com/watch?v=-_9BYSDtwRc")
		insert into ycurs values("https://youtube.com/watch?v=JpNg8Z75sEs")
		sele ycurs
		locate
	ENDPROC

	PROCEDURE olecontrol1.Init
		this.silent=.t.
	ENDPROC

ENDDEFINE
*
*-- EndDefine:ytlightbox


Playing with Youtube medias (video-audio)

Click on code to select [then copy] -click outside to deselect


thes code *4*  below builds a youtube player drived from visual foxpro.
VFP send commands via DOM architecture to scripts inside the javascript code.

can make new settings and rebuild the player(all settings are initialized with the JSAPI to build the player
and cannot reached dynamically.
the buttons play,pause,stop,mute,unMute are drived from vfp with a intermediar javascript function named "callplayer"
accepting arguments sent from vfp.
there is more 25 youtube player shortcuts can be sent manually as commands but the player must have mandatory the focus.
this focus can be done with a simple click on (or dblclick if its running to dont pause it).these shortcuts can be enabled/disabled (see property disablekb=0,1 )
For shortcuts can read http://www.hongkiat.com/blog/youtube-keyboard-shortcuts/

the button "commands" send some shortcuts to the player (remember it must have focus).
i tried to command by vfp the volume (getvolume(), setVolume(0-100%) unsuccessfully.
i tried also to make the currentTime()/Duration but controls updates are not supported with IE11 (and its browser) even in non protected mode set.its supported as well in Firefox !
the fullscreen is limited to the form area , can maximize the form and cut the titlebar...



Click on code to select [then copy] -click outside to deselect

*4* created on 27 of march 2017

publi oform
oform=newObject("youtube")
oform.show
read events
retu
*
DEFINE CLASS youtube AS form
	BorderStyle = 3
	Height = 602
	Width = 950
	ShowWindow = 2
	ShowTips = .T.
	AutoCenter = .T.
	Caption = "Form1"
	BackColor = RGB(0,0,0)
	yvideoid = .F.
	Name = "Form1"

	ADD OBJECT olecontrol1 AS olecontrol WITH ;
        Oleclass="shell.explorer.2" ,;
		Top = 0, ;
		Left = 0, ;
		Height = 535, ;
		Width = 948, ;
		Anchor = 15, ;
		Name = "Olecontrol1"

	ADD OBJECT container1 AS ycont WITH ;
		Anchor = 768, ;
		Top = 540, ;
		Left = 3, ;
		Width = 945, ;
		Height = 63, ;
		BackStyle = 1, ;
		BorderWidth = 0, ;
		BackColor = RGB(0,0,0), ;
		Name = "Container1"

	PROCEDURE ybuild
		*function callPlayer from http://jsfiddle.net/kmturley/g6P5H/296/
		local m.x
		text to  m.x textmerge  noshow
		<body scroll="no" bgcolor=black>		
		<div id="player" ></div>
		<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
		<script>
		var   time_update_interval = 0;
		
		var tag = document.createElement('script');
		tag.src = "https://www.youtube.com/iframe_api";
		var firstScriptTag = document.getElementsByTagName('script')[0]; firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);

		var player; function onYouTubeIframeAPIReady() {
		    player = new YT.Player('player', {
		    height: '<<thisform.olecontrol1.height-20>>',      // Player height (in px)
		    width: '<<thisform.olecontrol1.width>>',          // Player width (in px)
		
		  playerVars: {
			color: 'white',
			controls:<<thisform.xcontrols>> ,    // Show pause/play buttons in player
			enablejsapi:<<thisform.xenablejsapi>> ,
			frameborder:<<thisform.xframeborder>> ,
			allowfullscreen:<<thisform.xallowfullscreen>> ,
			autoplay:<<thisform.xautoplay>> ,     // Auto-play the video on load or no
			modestbranding:<<thisform.xmodestbranding>> ,   // Hide the Youtube Logo or no
			disablekb:<<thisform.xdisablekb>> ,
			fs:<<thisform.xfs>> ,        // Hide the full screen button or no
			loop:<<thisform.xloop>> ,        // Run the video in a loop or no
			showinfo:<<thisform.xshowInfo>>,   // Hide the video title or no
			rel:<<thisform.xrel>>,
			autohide:<<thisform.xautohide>>,	  // Hide video controls when playing or no
			cc_load_policty: 0, // Hide closed captions
		    iv_load_policy: 3,  // Hide the Video Annotations
			},
		 videoId: '<<allt(thisform.container1.combo1.value)>>',  //YouTube Video ID (unique like sys(2015) in vfp)
		
		    events: {
		      'onReady':onPlayerReady
		
		    }   }); }

		function onPlayerReady(event) { event.target.playVideo();}
		function callPlayer(frame_id, func, args) {
		    if (window.jQuery && frame_id instanceof jQuery) frame_id = frame_id.get(0).id;
		    var iframe = document.getElementById(frame_id);
		    if (iframe && iframe.tagName.toUpperCase() != 'IFRAME') {
		        iframe = iframe.getElementsByTagName('iframe')[0];
		    }
		    if (iframe) {
		        // Frame exists,
		        iframe.contentWindow.postMessage(JSON.stringify({
		            "event": "command",
		            "func": func,
		            "args": args || [],
		            "id": frame_id
		        }), "*");
		
		
		// alert(func+"  "+args);
		    }
		}
		</script>
		 endtext
		
		 local m.lcdest
		 m.lcdest=addbs(sys(2023))+"ytemp.html"
		 strtofile(m.x,m.lcdest)
		 thisform.olecontrol1.navigate(m.lcdest)
		
		 thisform.caption="VideoID="+thisform.container1.combo1.value
	ENDPROC

	PROCEDURE yshell
		lparameters arg
		if !pcount()=1
		return .f.
		endi

		if!vartype(arg)="C"
		return .f.
		endi

		*try
		local oo
		oo=newObject("wscript.shell")
		thisform.olecontrol1.setfocus()
		oo.sendkeys(m.arg)
		oo=null
		*catch
		*endtry

		with thisform.container1.yinfo
		do case
		case arg=" "
		.caption="Play/pause"
		case arg="{UP}"
		.caption="Volume up"
		case arg="{DOWN}"
		.caption="Volume down"
		case arg="{K}"
		.caption="Mute /unMute"
		case arg="{L}"
		.caption="Backwars 10s"
		case arg="{J}"
		.caption="Forward 10s"
		CASE ARG="{HOME}"
		.caption="Restart video"
		CASE ARG="{END}"
		.caption="End video"
		case arg="{>}"
		.caption="increase play speed"
		case arg="{<}"
		.caption="decrease play speed"
		case arg="{F}"
		.caption="Fullscreen on/off"
		case arg="{ESC}"
		.caption="Fullscreen OFF"
		endcase
		endwith
	ENDPROC

	PROCEDURE Destroy
		erase addbs(sys(2023))+"ytemp.html"
		clea events
	ENDPROC

	PROCEDURE Resize
		thisform.olecontrol1.resize
	ENDPROC

	PROCEDURE Init
		with thisform
		.container1.top=.height-.container1.height-1
		
		.addproperty("xenablejsapi",1)
		.addproperty("xcontrols",0)
		.addproperty("xshowinfo" ,0)
		.addproperty("xframeborder",0)
		.addproperty("xallowfullscreen",1)
		.addproperty("xautoplay",1)
		.addproperty("xmodestbranding",0)
		.addproperty("xdisablekb",0)
		.addproperty("xfs",1)
		.addproperty("xloop",0)
		.addproperty("xrel",0)
		.addproperty("xautohide",0)
		.ybuild()
		endwith
	ENDPROC

	PROCEDURE Load
		set safe off
		_screen.windowstate=1
	ENDPROC

	PROCEDURE olecontrol1.Resize
		try
		with this.document.getelementById("player").style
		.width=thisform.width
		.height=thisform.height-thisform.container1.height
		endwith
		catch
		endtry
	ENDPROC

	PROCEDURE olecontrol1.Init
		this.silent=.t.
		set safe off
	ENDPROC

ENDDEFINE
*
*-- EndDefine: youtube


*
DEFINE CLASS ycont AS container
	Anchor = 768
	Top = 540
	Left = 3
	Width = 945
	Height = 63
	BackStyle = 1
	BorderWidth = 0
	BackColor = RGB(0,0,0)
	Name = "Container1"

	ADD OBJECT command4 AS commandbutton WITH ;
		Top = 10, ;
		Left = 19, ;
		Height = 25, ;
		Width = 65, ;
		FontBold = .T., ;
		Anchor = 768, ;
		Caption = "Settings", ;
		MousePointer = 15, ;
		SpecialEffect = 2, ;
		BackColor = RGB(128,0,64), ;
		Name = "Command4"

	ADD OBJECT command5 AS commandbutton WITH ;
		Top = 10, ;
		Left = 86, ;
		Height = 25, ;
		Width = 60, ;
		FontBold = .T., ;
		Anchor = 768, ;
		Caption = "Rebuild", ;
		MousePointer = 15, ;
		SpecialEffect = 2, ;
		BackColor = RGB(255,0,0), ;
		Name = "Command5"

	ADD OBJECT command1 AS commandbutton WITH ;
		Top = 10, ;
		Left = 272, ;
		Height = 25, ;
		Width = 50, ;
		FontBold = .T., ;
		FontName = "Webdings", ;
		FontSize = 20, ;
		Anchor = 768, ;
		Caption = "4", ;
		MousePointer = 15, ;
		ToolTipText = "Play", ;
		SpecialEffect = 2, ;
		ForeColor = RGB(255,0,0), ;
		BackColor = RGB(128,255,128), ;
		Name = "Command1"

	ADD OBJECT command2 AS commandbutton WITH ;
		Top = 10, ;
		Left = 325, ;
		Height = 25, ;
		Width = 50, ;
		FontBold = .T., ;
		FontSize = 14, ;
		Anchor = 768, ;
		Caption = "II", ;
		MousePointer = 15, ;
		ToolTipText = "Pause", ;
		SpecialEffect = 2, ;
		ForeColor = RGB(255,0,0), ;
		BackColor = RGB(128,255,128), ;
		Name = "Command2"

	ADD OBJECT command3 AS commandbutton WITH ;
		Top = 10, ;
		Left = 377, ;
		Height = 25, ;
		Width = 50, ;
		FontBold = .T., ;
		FontName = "Webdings", ;
		FontSize = 12, ;
		Anchor = 768, ;
		Caption = "1", ;
		MousePointer = 15, ;
		ToolTipText = "Stop", ;
		SpecialEffect = 2, ;
		ForeColor = RGB(255,0,0), ;
		BackColor = RGB(128,255,128), ;
		Name = "Command3"

	ADD OBJECT check1 AS checkbox WITH ;
		Top = 10, ;
		Left = 429, ;
		Height = 25, ;
		Width = 93, ;
		FontBold = .T., ;
		Anchor = 768, ;
		AutoSize = .T., ;
		Alignment = 0, ;
		Caption = "Mute/unMute", ;
		Value = 0, ;
		MousePointer = 15, ;
		Style = 1, ;
		BackColor = RGB(128,255,128), ;
		Name = "Check1"

	ADD OBJECT combo1 AS combobox WITH ;
		FontSize = 8, ;
		Height = 25, ;
		Left = 152, ;
		Top = 10, ;
		Width = 114, ;
		ForeColor = RGB(255,0,0), ;
		Name = "Combo1"

	ADD OBJECT label1 AS label WITH ;
		AutoSize = .T., ;
		FontBold = .T., ;
		FontSize = 20, ;
		BackStyle = 0, ;
		Caption = "?", ;
		Height = 35, ;
		Left = 873, ;
		MousePointer = 15, ;
		Top = 10, ;
		Width = 19, ;
		ForeColor = RGB(0,255,0), ;
		Name = "Label1"

	ADD OBJECT command8 AS commandbutton WITH ;
		Top = 10, ;
		Left = 560, ;
		Height = 25, ;
		Width = 84, ;
		FontBold = .T., ;
		FontSize = 10, ;
		Anchor = 768, ;
		Caption = "Commands", ;
		MousePointer = 15, ;
		SpecialEffect = 2, ;
		BackColor = RGB(128,255,128), ;
		Name = "Command8"

	ADD OBJECT command9 AS commandbutton WITH ;
		Top = 9, ;
		Left = 645, ;
		Height = 27, ;
		Width = 96, ;
		FontBold = .T., ;
		Caption = "Actual Settings", ;
		MousePointer = 15, ;
		ToolTipText = "Actual settings", ;
		BackColor = RGB(128,255,0), ;
		Name = "Command9"

	ADD OBJECT yinfo AS label WITH ;
		FontBold = .T., ;
		FontSize = 12, ;
		Alignment = 2, ;
		BackStyle = 0, ;
		Caption = ".....", ;
		Height = 25, ;
		Left = 137, ;
		Top = 37, ;
		Width = 745, ;
		ForeColor = RGB(255,0,0), ;
		Name = "yinfo"

	ADD OBJECT shape1 AS shape WITH ;
		Top = 13, ;
		Left = 910, ;
		Height = 25, ;
		Width = 25, ;
		Curvature = 99, ;
		MousePointer = 15, ;
		ToolTipText = "fORM TITLEBAR ON/OFF", ;
		BackColor = RGB(0,255,0), ;
		Name = "Shape1"
		
	ADD OBJECT timer1 AS timer with ;
	Enabled = .T.,;
	Interval = 10000,;
	Name = "Timer1"


	PROCEDURE Timer1.timer
		if !empty(this.parent.yinfo.caption)
		this.parent.yinfo.caption=""
		endi
	ENDPROC
	
	PROCEDURE command4.Click
		this.rightclick()
	ENDPROC

	PROCEDURE command4.RightClick
		DEFINE POPUP raccourci  COLOR  N+/w*,R+/w*,,,,W+/R SHORTCUT RELATIVE FROM MROW(),MCOL()
		DEFINE BAR 1 OF raccourci PROMPT "autoplay"
		DEFINE BAR 2 OF raccourci PROMPT "controls"
		DEFINE BAR 3 OF raccourci PROMPT "showinfo"
		DEFINE BAR 4 OF raccourci PROMPT "allowfullscreen"
		DEFINE BAR 5 OF raccourci PROMPT "modestbranding"
		DEFINE BAR 6 OF raccourci PROMPT "disablekb"
		DEFINE BAR 7 OF raccourci PROMPT "fs"
		DEFINE BAR 8 OF raccourci PROMPT "loop"
		DEFINE BAR 9 OF raccourci PROMPT "rel"
		DEFINE BAR 10 OF raccourci PROMPT "autohide"

		ON BAR 1 OF raccourci ACTIVATE POPUP autoplay
		ON BAR 2 OF raccourci ACTIVATE POPUP controls
		ON BAR 3 OF raccourci ACTIVATE POPUP showinfo
		ON BAR 4 OF raccourci ACTIVATE POPUP allowfulls
		ON BAR 5 OF raccourci ACTIVATE POPUP modestbran
		ON BAR 6 OF raccourci ACTIVATE POPUP disablekb
		ON BAR 7 OF raccourci ACTIVATE POPUP fs
		ON BAR 8 OF raccourci ACTIVATE POPUP loop
		ON BAR 9 OF raccourci ACTIVATE POPUP rel
		ON BAR 10OF raccourci ACTIVATE POPUP autohide

		DEFINE POPUP autoplay SHORTCUT RELATIVE
		DEFINE BAR 1 OF autoplay PROMPT "0"
		DEFINE BAR 2 OF autoplay PROMPT "1"
		ON SELECTION BAR 1 OF autoplay _screen.activeform.xautoplay=iif(_screen.activeform.xautoplay=0,1,0)
		ON SELECTION BAR 2 OF autoplay _screen.activeform.xautoplay=iif(_screen.activeform.xautoplay=0,1,0)

		DEFINE POPUP controls SHORTCUT RELATIVE
		DEFINE BAR 1 OF controls PROMPT "0"
		DEFINE BAR 2 OF controls PROMPT "1"
		ON SELECTION BAR 1 OF controls _screen.activeform.xcontrols=iif(_screen.activeform.xcontrols=0,1,0)
		ON SELECTION BAR 2 OF controls _screen.activeform.xcontrols=iif(_screen.activeform.xcontrols=0,1,0)

		DEFINE POPUP showinfo SHORTCUT RELATIVE
		DEFINE BAR 1 OF showinfo PROMPT "0"
		DEFINE BAR 2 OF showinfo PROMPT "1"
		ON SELECTION BAR 1 OF showinfo _screen.activeform.xshowinfo=iif(_screen.activeform.xshowinfo=0,1,0)
		ON SELECTION BAR 2 OF showinfo _screen.activeform.xshowinfo=iif(_screen.activeform.xshowinfo=0,1,0)
		DEFINE POPUP allowfulls SHORTCUT RELATIVE
		DEFINE BAR 1 OF allowfulls PROMPT "0"
		DEFINE BAR 2 OF allowfulls PROMPT "1"
		ON SELECTION BAR 1 OF allowfulls _screen.activeform.xallowFullscreen=iif(_screen.activeform.xallowFullscreen=0,1,0)
		ON SELECTION BAR 2 OF allowfulls _screen.activeform.xallowFullscreen=iif(_screen.activeform.xallowFullscreen=0,1,0)

		DEFINE POPUP modestbran SHORTCUT RELATIVE
		DEFINE BAR 1 OF modestbran PROMPT "0"
		DEFINE BAR 2 OF modestbran PROMPT "1"
		ON SELECTION BAR 1 OF modestbran _screen.activeform.xmodestbranding=iif(_screen.activeform.xmodestbranding=0,1,0)
		ON SELECTION BAR 2 OF modestbran _screen.activeform.xmodestbranding=iif(_screen.activeform.xmodestbranding=0,1,0)

		DEFINE POPUP disablekb SHORTCUT RELATIVE
		DEFINE BAR 1 OF disablekb PROMPT "0"
		DEFINE BAR 2 OF disablekb PROMPT "1"
		ON SELECTION BAR 1 OF disablekb _screen.activeform.xdisablekb=iif(_screen.activeform.xdisablekb=0,1,0)
		ON SELECTION BAR 2 OF disablekb _screen.activeform.xdisablekb=iif(_screen.activeform.xdisablekb=0,1,0)

		DEFINE POPUP fs SHORTCUT RELATIVE
		DEFINE BAR 1 OF fs PROMPT "0"
		DEFINE BAR 2 OF fs PROMPT "1"
		ON SELECTION BAR 1 OF fs _screen.activeform.xfs=iif(_screen.activeform.xfs=0,1,0)
		ON SELECTION BAR 2 OF fs _screen.activeform.xfs=iif(_screen.activeform.xfs=0,1,0)

		DEFINE POPUP loop SHORTCUT RELATIVE
		DEFINE BAR 1 OF loop PROMPT "0"
		DEFINE BAR 2 OF loop PROMPT "1"
		ON SELECTION BAR 1 OF loop _screen.activeform.xloop=iif(_screen.activeform.xloop=0,1,0)
		ON SELECTION BAR 2 OF loop _screen.activeform.xloop=iif(_screen.activeform.xloop=0,1,0)

		DEFINE POPUP rel SHORTCUT RELATIVE
		DEFINE BAR 1 OF rel PROMPT "0"
		DEFINE BAR 2 OF rel PROMPT "1"
		ON SELECTION BAR 1 OF loop _screen.activeform.xrel=iif(_screen.activeform.xrel=0,1,0)
		ON SELECTION BAR 2 OF loop _screen.activeform.xrel=iif(_screen.activeform.xrel=0,1,0)

		DEFINE POPUP autohide SHORTCUT RELATIVE
		DEFINE BAR 1 OF autohide  PROMPT "0"
		DEFINE BAR 2 OF autohide  PROMPT "1"
		ON SELECTION BAR 1 OF autohide _screen.activeform.xautohide=iif(_screen.activeform.xautohide =0,1,0)
		ON SELECTION BAR 2 OF autohide  _screen.activeform.xautohide=iif(_screen.activeform.xautohide =0,1,0)

		ACTIVATE POPUP raccourci
	ENDPROC

	PROCEDURE command5.Click
		local m.x
		text to m.x textmerge pretext 7 noshow
		*Once the Youtube player is loaded it initialize all its parameters (properties).
		*these cannot modfified at runtime.
		*must rebuild the player to set some other properties or to change someones.
			controls:<<thisform.xcontrols>>
			frameborder:<<thisform.xframeborder>> ,
			allowfullscreen:<<thisform.xallowfullscreen>>
			autoplay:<<thisform.xautoplay>>
			modestbranding:<<thisform.xmodestbranding>>
			disablekb:<<thisform.xdisablekb>>
			fs:<<thisform.xfs>>
			loop:<<thisform.xloop>>
			showinfo:<<thisform.xshowInfo>>
			rel:<<thisform.xrel>>
			autohide:<<thisform.xautohide>>
		endtext
		if messagebox("Want to reset player to these values ?"+chr(13)+m.x,4+64)=6
		thisform.ybuild()
		endi
	ENDPROC

	PROCEDURE command1.Click
		try
		this.parent.yinfo.caption="Playing"
		thisform.olecontrol1.document.script.callPlayer("player","playVideo")
		catch
		endtry
	ENDPROC

	PROCEDURE command2.Click
		try
		this.parent.yinfo.caption="Paused!"
		thisform.olecontrol1.document.script.callPlayer("player","pauseVideo")
		catch
		endtry
	ENDPROC

	PROCEDURE command3.Click
		try
		this.parent.yinfo.caption="Stopped!"
		thisform.olecontrol1.document.script.callPlayer("player","stopVideo")
		catch
		endtry
	ENDPROC

	PROCEDURE check1.Click
		try
		if this.value=1
		this.parent.yinfo.caption="Muted"
		thisform.olecontrol1.document.script.callPlayer("player","mute")
		else
		this.parent.yinfo.caption="unMuted"
		thisform.olecontrol1.document.script.callPlayer("player","unMute")
		endi
		catch
		endtry
	ENDPROC

	PROCEDURE combo1.Init
		with this
		.additem("Xa0Q0J5tOP0")
		.additem("M7lc1UVf-VE")
		.additem("INLzqh7rZ-U")
		.additem("0Bmhjf0rKe8")
		.additem("Gs8lACWtL-A")
		.additem("YfKfU8rQGKA")
		.additem("JtHrsXEa7d4")
		.additem("M6p1_9MR5PQ")
		.additem("gwinFP8_qIM")
		.additem("-_9BYSDtwRc")
		.additem("JpNg8Z75sEs")
		.listindex=1
		.style=2
		endwith
	ENDPROC

	PROCEDURE combo1.InteractiveChange
		thisform.yvideoId=allt(this.value)
		thisform.ybuild()
	ENDPROC

	PROCEDURE label1.Click
		declare integer BringWindowToTop in user32 integer HWND
		local apie
		apie=newObject("internetexplorer.application")
		with apie
		.navigate("https://developers.google.com/youtube/player_parameters?hl=fr#modestbranding")
		.menubar=0
		.toolbar=0
		.statusbar=0
		.width=900
		.height=650
		.top=10
		bringWindowToTop(.hwnd)
		.visible=.t.
		endwith
	ENDPROC

	PROCEDURE command8.RightClick
		IF THISFORM.xdisablekb=1
		messagebox("xdisablekb property must be =0 to enable keyboards shortcuts",16+4096,'',1300)
		return .f.
		endi
		*COLOR  R/w*,G/w*,,,,W+/R
		DEFINE POPUP raccourci   COLOR  N+/w*,RB/GR*,,,,W+/BG SHORTCUT RELATIVE FROM MROW(),MCOL()
		DEFINE BAR 1 OF raccourci PROMPT "Pause/Play"
		DEFINE BAR 2 OF raccourci PROMPT "Volume up"
		DEFINE BAR 3 OF raccourci PROMPT "Volume down"
		DEFINE BAR 4 OF raccourci PROMPT "Mute /unMute"
		DEFINE BAR 5 OF raccourci PROMPT "Backwars 10s"
		DEFINE BAR 6 OF raccourci PROMPT "Forward 10s"
		DEFINE BAR 7 OF raccourci PROMPT "Restart video"
		DEFINE BAR 8 OF raccourci PROMPT "End video"
		DEFINE BAR 9 OF raccourci PROMPT "Increase play speed"
		DEFINE BAR 10 OF raccourci PROMPT "decrease play speed"
		DEFINE BAR 11 OF raccourci PROMPT "Fullscreen on/off"
		DEFINE BAR 12 OF raccourci PROMPT "Fullscreen OFF"

		ON SELECTION BAR 1 OF raccourci _screen.activeform.yshell(" ")
		ON SELECTION BAR 2 OF raccourci _screen.activeform.yshell("{UP}")
		ON SELECTION BAR 3 OF raccourci _screen.activeform.yshell("{DOWN}")
		ON SELECTION BAR 4 OF raccourci _screen.activeform.yshell("{K}")
		ON SELECTION BAR 5 OF raccourci _screen.activeform.yshell("{L}")
		ON SELECTION BAR 6 OF raccourci _screen.activeform.yshell("{L}")
		ON SELECTION BAR 7 OF raccourci _screen.activeform.yshell("{HOME}")
		ON SELECTION BAR 8 OF raccourci _screen.activeform.yshell("{END}")
		ON SELECTION BAR 9 OF raccourci _screen.activeform.yshell("{>}")
		ON SELECTION BAR 10 OF raccourci _screen.activeform.yshell("{<}")
		ON SELECTION BAR 11 OF raccourci _screen.activeform.yshell("{F}")
		ON SELECTION BAR 12 OF raccourci _screen.activeform.yshell("{ESC}")
		ACTIVATE POPUP raccourci
		*!*1	pause/play
		*!*2	volume up
		*!*3	Volume down
		*!*4	mute/unmute
		*!*5	Backward 10s
		*!*6	Forward 10s
		*!*7	Restart video
		*!*8	end video
		*!*9	increase play speed
		*!*10	decrease play speed
		*!*11 fullscreen
	ENDPROC

	PROCEDURE command8.Click
		this.rightclick
	ENDPROC

	PROCEDURE command9.Click
		local m.x
		text to m.x textmerge pretext 7 noshow
		youtube player actual  Settings :
		*
			controls:<<thisform.xcontrols>>
			frameborder:<<thisform.xframeborder>> ,
			allowfullscreen:<<thisform.xallowfullscreen>>
			autoplay:<<thisform.xautoplay>>
			modestbranding:<<thisform.xmodestbranding>>
			disablekb:<<thisform.xdisablekb>>
			fs:<<thisform.xfs>>
			loop:<<thisform.xloop>>
			showinfo:<<thisform.xshowInfo>>
			rel:<<thisform.xrel>>
			autohide:<<thisform.xautohide>>
		endtext
		messagebox(+m.x,0+32+4096,"Settings")
	ENDPROC

	PROCEDURE shape1.Click
		with thisform
		.titlebar=IIF (.titlebar=1,0,1)
		if .titlebar=0
		.height=.height+sysmetric(9)+sysmetric(4)
		else
		.height=.height-sysmetric(9)-sysmetric(4)
		endi
		endwith
	ENDPROC

ENDDEFINE
*
*-- EndDefine: ycont


if set controls=1 the native YT toolbar appears at bottom of video.

if set controls=1 the native YT toolbar appears at bottom of video.

Click on code to select [then copy] -click outside to deselect


*5* created on 27 of march 2017
*this code extractS all valid youtube videoIds succinctully  from web urls shippedin many formats
*this is a test on 12 kinds of YT urls and it uses the RegExp activeX (shipped on any windows OS(to confirm) ).


Local RegEx As VBScript.RegExp
m.RegEx = Createobject("VBScript.RegExp")
m.RegEx.Ignorecase = .F.
m.RegEx.Multiline = .F.
m.RegEx.Global = .T.
m.RegEx.Pattern ="(\/watch\?v\=|\/\w+\?v=|\/|v=)([a-zA-Z0-9\-]+)(\s*$|\?|\&)"

*the pattern below down work here ? tried in javascript and it works as well
*m.RegEx.Pattern ='/https?:\/\/(?:[0-9A-Z-]+\.)?(?:youtu\.be\/|youtube\.com(?:\/embed\/|\/v\/|\/watch\?v=|\/ytscreeningroom\?v=|\/feeds\/api\/videos\/|\/user\S*[^\w\-\s]|\S*[^\w\-\s]))([\w\-]{11})[?=&+%\w-]*/ig;'


Local m.xURL As String

Create Cursor YCURS (url c(80),videoID c(20))

Set Memowidth To 8192
TEXT TO m.Source NOSHOW
http://youtu.be/NLqAF9hrVbY
http://www.youtube.com/embed/NLqAF9hrVbY
https://www.youtube.com/embed/NLqAF9hrVbY
http://www.youtube.com/v/NLqAF9hrVbY?fs=1&hl=en_US
http://www.youtube.com/watch?v=NLqAF9hrVbY
http://www.youtube.com/user/Scobleizer#p/u/1/1p3vcRhsYGo
http://www.youtube.com/ytscreeningroom?v=NRHVzbJVx8I
http://www.youtube.com/sandalsResorts#p/c/54B8C800269D7C1B/2/PPS-8DMrAn4
http://gdata.youtube.com/feeds/api/videos/NLqAF9hrVbY
http://www.youtube.com/watch?v=spDj54kf-vY&feature=g-vrec
http://www.youtube.com/watch?v=GUEZCxBcM78&feature=pyv&feature=pyv&ad=10059374899&kw=%2Bwingsuit
https://youtu.be/ieZvRKtRGqE
ENDTEXT
For i=1 To Memlines(m.source)
	Insert Into YCURS Values(Mline(m.source,i),"")
Endfor

Local SampleIndex
Scan
	m.xURL=Allt(url)  &&important
	m.Matches  = m.RegEx.Execute(m.xURL)
	Repl videoID  With (m.Matches.Item(0).SubMatches(1))
Endscan

*brow
Locate
Browse Name oBr  Title "Youtube video player VideoIds "   Nowait Noedit
With oBr
	.DeleteMark=.F.
	.RecordMark=.F.
	.GridLines=0
	.RowHeight=22
	.FontBold=.T.
	.SetAll("DynamicBackColor", "IIF(MOD(RECNO( ), 2)=0, RGB(205,200,198) , RGB(200,215,0))", "Column")
Endwith
Retu


Playing with Youtube medias (video-audio)

Remarks and notes:
1-All youtube video player properties are in this page :https://developers.google.com/youtube/player_parameters
can  build a youtube prototype  videoplayer from vfp  (always in a web page). with these properties....
2.if compile an exe can read playlist videoIds from an external  dbf or a txt file (instead of recompiling each time the exe).can tweak the code in form.load to accomplish this.for ex.put all videoIds playlist in a txt file and mark it as excluded in the project and fill the cursor ycurs (1 record=1txt line).....this file can be modifiable by the user.
3-properties used here: quality,duration,speed,navigation (play/pause/stop/next/previous,first ,last-progressbar,duration...)
4-if want no ads on player issue ...rel=0 in properties (as code above).
5-All these stay available while Google dont deprecate its JSAPI !


Important:All Codes above are tested on VFP9SP2 & windows 10 pro and IE11 emulation

Comment on this post