Using Youtube Javascript API for multiple videos - api

I am trying to find a way to use Youtube API to have multiple videos with each in its own hidden div where each one is called up by their corresponding thumbnails. I am having a hard time finding out how to get the close button of the once hidden div to also stop that particular video. I can only get one to do it right and the other will not. My code below:
// 2. This code loads the IFrame Player API code asynchronously.
var tag = document.createElement('script');
tag.src = "//www.youtube.com/iframe_api";
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
// 3. This function creates an <iframe> (and YouTube player)
// after the API code downloads.
var player;
function onYouTubeIframeAPIReady() {
player1 = new YT.Player('popupVid1', {
height: '408',
width: '725',
videoId: '6Bp1c3-AeXQ',
playerVars: {
wmode: "opaque"
},
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
player2 = new YT.Player('popupVid2', {
height: '408',
width: '725',
videoId: '6Bp1c3-AeXQ',
playerVars: {
wmode: "opaque"
},
events: {
'onReady': onPlayerReady,
'onStateChange': onPlayerStateChange
}
});
}
// 4. The API will call this function when the video player is ready.
function onPlayerReady(event) {
event.target.playVideo();
}
// 5. The API calls this function when the player's state changes.
// The function indicates that when playing a video (state=1),
// the player should play for six seconds and then stop.
var done = false;
function onPlayerStateChange(event) {
if (event.data == YT.PlayerState.PLAYING && !done) {
setTimeout(stopVideo,loop);
done = true;
}
}
function stopVideo1() {
player1.stopVideo();
}
function stopVideo2() {
player2.stopVideo();
}

Related

VueJS Leaflet 'moveend' fires multiple times

Ask for help from the community. For two weeks I can not overcome the problem with repeated firing of 'mooveend' in the project. I have tried all the advice given here. Here's what I've read and researched already, but it didn't work for me.
This is one of the tips:
moveend event fired many times when page is load with Leaflet
<template>
<div id="map"></div>
</template>
<script>
export default {
name: "ObjectMapView",
props: ['coordinate'],
data: function () {
return {
map: null,
addressPoints: null,
markers: null,
}
},
mounted: function() {
this.initializedMap();
},
watch: {
coordinate: function (val) {
this.run();
}
},
methods: {
initializedMap: function () {
this.map = L.map('map').setView([52.5073390000,5.4742833000], 13);
L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap contributors'
}).addTo(this.map);
this.markers = L.markerClusterGroup();
},
run: function () {
var map = this.map;
var markers = this.markers;
var getAllObjects = this.coordinate;
var getBoundsMarkers;
//Clearing Layers When Switching a Filter
markers.clearLayers();
this.addressPoints = getAllObjects.map(function (latlng){
return [latlng.latitude, latlng.longitude, latlng.zip, latlng.object_id, latlng.archived];
});
map.addLayer(markers);
//We give to the map only those coordinates that are in the zone of visibility of the map during the first
getBoundsMarkers = getAllObjects.filter((coord) => {
if(!coord.latitude && !coord.longitude){
return false;
}
return map.getBounds().contains(L.latLng(coord.latitude, coord.longitude));
});
/*
Responds to changing the boundaries of the map visibility zone and
transmits a list of coordinates that are in the visibility zone
*/
console.log('getAllObjects_1', getAllObjects);
map.on('moveend', function() {
console.log('moveend');
console.log('getAllObjects_2', getAllObjects);
getBoundsMarkers = getAllObjects.filter((coord) => {
if(!coord.latitude && !coord.longitude){
return false;
}
return map.getBounds().contains(L.latLng(coord.latitude, coord.longitude));
});
eventHub.$emit('sendMarkers', getBoundsMarkers);
});
// In the loop, we iterate over the coordinates and give them to the map
for (var i = 0; i < this.addressPoints.length; i++) {
var a = this.addressPoints[i];
var title = '' + a[2] + ''; //bubble
var marker = L.marker(new L.LatLng(a[0], a[1]), {
title: title
});
marker.bindPopup(title);
markers.addLayer(marker);
}
eventHub.$emit('sendMarkers', getBoundsMarkers);
}
}
}
</script>
<style scoped>
#map {
width: 97%;
height: 100%;
}
</style>
I figured it out myself.
The 'zoomend' and 'dragend' option didn't work for me. I searched a lot for a suitable option and realized that the "moveend" event fires several times because this event is created every time you move the map. Therefore it is necessary to stop this event. I got out of the situation in this way. Immediately after the map was initialized, I wrote:
map.off('moveend');
and for me it worked. Now it works fine. I will be very happy if this is useful to someone.

Record Audio for Android and iOS using Appcelerator Titanium

I'm having problems trying to record audio into a file. I'm trying to run the sample code (with the required permissions in the tiapp.xml) but i'm always getting errors (like "+[NSBlock boundBridge:withKrollObject:]: unrecognized selector sent to class 0x1b5549500"; at the stop() action).
I can't find a module for audio recording (i've used the tutorial.audiorecord but it doesn't work in newest versions of SDK)
This is the sample code from the appcelerator documentation page https://docs.appcelerator.com/platform/latest/#!/api/Titanium.Media.AudioRecorder
I try everything but doesn't work.
Someone have a working example or a module for Appcelerator SDK 7?
var window = Ti.UI.createWindow({
backgroundColor: '#fff'
});
var recordStart = Ti.UI.createButton({
title: 'Start',
top: 10
});
var recordPause = Ti.UI.createButton({
title: 'Pause',
top: 60
});
var recordStop = Ti.UI.createButton({
title: 'Stop',
top: 110
});
var recordPlay = Ti.UI.createButton({
title: 'Play',
top: 160
});
var audioRecorder = Ti.Media.createAudioRecorder();
var record;
var audioPlayer;
window.addEventListener('open', function(e) {
if (!Ti.Media.hasAudioRecorderPermissions()) {
Ti.Media.requestAudioRecorderPermissions(function(e) {
if (e.success) {
window.add(recordStart);
}
});
} else {
window.add(recordStart);
}
});
recordStart.addEventListener('click', function(e) {
audioRecorder.start();
});
recordPause.addEventListener('click', function(e) {
if (audioRecorder.getPaused()) {
recordPause.setTitle('Pause');
audioRecorder.resume();
} else {
recordPause.setTitle('Resume');
audioRecorder.pause();
}
});
recordStop.addEventListener('click', function(e) {
record = audioRecorder.stop();
Ti.API.info(record.getNativePath());
});
recordPlay.addEventListener('click', function(e) {
audioPlayer = Ti.Media.createAudioPlayer({
url: record.getNativePath()
});
audioPlayer.start();
});
window.add(recordPause);
window.add(recordStop);
window.add(recordPlay);
window.open();
Thanks in advance
This is an example using Titanium's Hyperloop: https://gist.github.com/dinahgarcia/119ac00c91334d3951601cf347bad8d4
To be able to use it you need to enable Hyperloop: https://docs.appcelerator.com/platform/latest/#!/guide/Enabling_Hyperloop

ArcGIS Online WebMap authentication timeout

I have an ArcGIS Online public account and add WebMap to my website.
My ArcGIS Online WebMap looks like this ESRI's sample: LINK
And I am trying to add my WebMap to my website like this ESRI's reference page. You will see there is a map in the center of page: LINK
My WebMap is displayed on my webpage well. When I access my webpage, my WebMap asks my ID and Password. If I entered it, then it shows my map.
However, my question is, if I moved to different page and then come back to map page, it asks again. Is it possible to set a timeout so I don't have to sign in everytime I access the page?
The reason I asked this question is that to find out if there were a way to reduce my code simple and work on code in front-end.
I've researched OAuth that ESRI provided and I ended up using esri/IdentityManager. There were references to use esri/IdentityManager package; however there were no sample code to using it with personal WebMap which used arcgisUtils.createMap
So here is sample code that I worked:
require([
"dojo/parser",
"dojo/ready",
"dijit/layout/BorderContainer",
"dijit/layout/ContentPane",
"dojo/dom",
"esri/map",
"esri/urlUtils",
"esri/arcgis/utils",
"esri/dijit/Legend",
"esri/dijit/LayerList",
"esri/graphic",
"esri/symbols/PictureMarkerSymbol",
"esri/symbols/TextSymbol",
"esri/geometry/Point",
"esri/dijit/Scalebar",
"dojo/_base/unload",
"dojo/cookie",
"dojo/json",
"esri/config",
"esri/IdentityManager",
"esri/layers/FeatureLayer",
"dojo/domReady!"
], function (
parser,
ready,
BorderContainer,
ContentPane,
dom,
Map,
urlUtils,
arcgisUtils,
Legend,
LayerList,
Graphic,
PictureMarkerSymbol,
TextSymbol,
Point,
Scalebar,
baseUnload,
cookie,
JSON,
esriConfig,
esriId,
FeatureLayer
) {
var mapOptions = {
basemap: "topo",
autoResize: true, // see http://forums.arcgis.com/threads/90825-Mobile-Sample-Fail
center: [currentPosition.lng, currentPosition.lat],
zoom: 15,
logo: false
};
// cookie/local storage name
var cred = "esri_jsapi_id_manager_data";
// store credentials/serverInfos before the page unloads
baseUnload.addOnUnload(storeCredentials);
// look for credentials in local storage
loadCredentials();
parser.parse();
esriConfig.defaults.io.proxyUrl = "/proxy/";
//Create a map based on an ArcGIS Online web map id
arcgisUtils.createMap('PUT-YOUR-ESRI-KEY', "esriMapCanvas", { mapOptions: mapOptions }).then(function (response) {
var map = response.map;
// add a blue marker
var picSymbol = new PictureMarkerSymbol(
'http://static.arcgis.com/images/Symbols/Shapes/RedPin1LargeB.png', 50, 50);
var geometryPoint = new Point('SET YOUR LAT', 'SET YOUR LONG');
map.graphics.add(new Graphic(geometryPoint, picSymbol));
//add the scalebar
var scalebar = new Scalebar({
map: map,
scalebarUnit: "english"
});
//add the map layers
var mapLayers = new LayerList({
map: map,
layers: arcgisUtils.getLayerList(response)
}, "esriLayerList");
mapLayers.startup();
//add the legend. Note that we use the utility method getLegendLayers to get
//the layers to display in the legend from the createMap response.
var legendLayers = arcgisUtils.getLegendLayers(response);
var legendDijit = new Legend({
map: map,
layerInfos: legendLayers
}, "esriLegend");
legendDijit.startup();
});
function storeCredentials() {
// make sure there are some credentials to persist
if (esriId.credentials.length === 0) {
return;
}
// serialize the ID manager state to a string
var idString = JSON.stringify(esriId.toJson());
// store it client side
if (supports_local_storage()) {
// use local storage
window.localStorage.setItem(cred, idString);
// console.log("wrote to local storage");
}
else {
// use a cookie
cookie(cred, idString, { expires: 1 });
// console.log("wrote a cookie :-/");
}
}
function supports_local_storage() {
try {
return "localStorage" in window && window["localStorage"] !== null;
} catch (e) {
return false;
}
}
function loadCredentials() {
var idJson, idObject;
if (supports_local_storage()) {
// read from local storage
idJson = window.localStorage.getItem(cred);
}
else {
// read from a cookie
idJson = cookie(cred);
}
if (idJson && idJson != "null" && idJson.length > 4) {
idObject = JSON.parse(idJson);
esriId.initialize(idObject);
}
else {
// console.log("didn't find anything to load :(");
}
}
});

Reverse Geocoding With Dynamic Form

I've been trying to find a way to use the 'Reverse Geocoding' service with the Latitude and Longitude co-ordinates coming from two text boxes on my HTML form, and I must admit I'm not really sure what I need to do.
I have managed to do this with the 'Geocode' service (see code below), but I just wondered whether someone may be able to point me in the right direction of how I could adapt the 'Geocode' javascript I have to the 'Reverse Geocoging' service.
(function Geocode() {
// This is defining the global variables
var map, geocoder, myMarker;
window.onload = function() {
//This is creating the map with the desired options
var myOptions = {
zoom: 5,
center: new google.maps.LatLng(55.378051,-3.435973),
mapTypeId: google.maps.MapTypeId.ROADMAP,
mapTypeControl: true,
mapTypeControlOptions: {
style: google.maps.MapTypeControlStyle.HORIZONTAL_BAR,
position: google.maps.ControlPosition.BOTTOM
},
navigationControl: true,
navigationControlOptions: {
style: google.maps.NavigationControlStyle.ZOOM_PAN,
position: google.maps.ControlPosition.TOP_RIGHT
},
scaleControl: true,
scaleControlOptions: {
position: google.maps.ControlPosition.BOTTOM_LEFT
}
};
map = new google.maps.Map(document.getElementById('map'), myOptions);
// This is making the link with the 'Search For Location' HTML form
var form = document.getElementById('SearchForLocationForm');
// This is catching the forms submit event
form.onsubmit = function() {
// This is getting the Address from the HTML forms 'Address' text box
var address = document.getElementById('GeocodeAddress').value;
// This is making the Geocoder call
getCoordinates(address);
// This is preventing the form from doing a page submit
return false;
}
}
// This creates the function that will return the coordinates for the address
function getCoordinates(address) {
// This checks to see if there is already a geocoded object. If not, it creates one
if(!geocoder) {
geocoder = new google.maps.Geocoder();
}
// This is creating a GeocoderRequest object
var geocoderRequest = {
address: address
}
// This is making the Geocode request
geocoder.geocode(geocoderRequest, function(results, status) {
// This checks to see if the Status is 'OK 'before proceeding
if (status == google.maps.GeocoderStatus.OK) {
// This centres the map on the returned location
map.setCenter(results[0].geometry.location);
// This creates a new marker and adds it to the map
var myMarker = new google.maps.Marker({
map: map,
zoom: 12,
position: results[0].geometry.location,
draggable:true
});
//This fills out the 'Latitude' and 'Longitude' text boxes on the HTML form
document.getElementById('Latitude').value= results[0].geometry.location.lat();
document.getElementById('Longitude').value= results[0].geometry.location.lng();
//This allows the marker to be draggable and tells the 'Latitude' and 'Longitude' text boxes on the HTML form to update with the new co-ordinates as the marker is dragged
google.maps.event.addListener(
myMarker,
'dragend',
function() {
document.getElementById('Latitude').value = myMarker.position.lat();
document.getElementById('Longitude').value = myMarker.position.lng();
var point = myMarker.getPosition();
map.panTo(point);
}
);
}
}
)
}
})();
UPDATE
Firstly, many thanks for the code you kindly posted and the suggestion to go and have a look at the Google documentation.
From what you suggested, and from what I took from the additional documentation I came up with the following. However, when I click my submit button nothing happens, almost as if there is no command attached to it. I don't receive any error messages and I've checked to make sure that I've linked the code to the correct fieldnames and all seems ok. I just wondered whether it would be at all possible if you, or indeed anyone else, could take a look at it please to tell me where I've gone wrong.
Many thanks and kind regards
(function ReverseGeocode() {
var form, geocoderRequest, latlng, myMarker, point;
window.onload = function() {
//This is creating the map with the desired options
var myOptions = {
zoom: 5,
center: new google.maps.LatLng(55.378051,-3.435973),
mapTypeId: google.maps.MapTypeId.ROADMAP,
mapTypeControl: true,
mapTypeControlOptions: {
style: google.maps.MapTypeControlStyle.HORIZONTAL_BAR,
position: google.maps.ControlPosition.BOTTOM
},
navigationControl: true,
navigationControlOptions: {
style: google.maps.NavigationControlStyle.ZOOM_PAN,
position: google.maps.ControlPosition.TOP_RIGHT
},
scaleControl: true,
scaleControlOptions: {
position: google.maps.ControlPosition.BOTTOM_LEFT
}
};
map = new google.maps.Map(document.getElementById('map'), myOptions);
var latlng = new google.maps.LatLng('Latitude', 'Longitude');
// This is making the Geocode request
geocoder.geocode({'LatLng': latlng}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
if (results[1]) {
map.setZoom(11);
var myMarker = new google.maps.Marker({
position: results[0].geometry.location,
map: map
});
//This fills out the 'Address' text boxe on the HTML form
document.getElementById('Address').value= results[0].geometry.location.latlng();
var point = myMarker.getPosition();
map.panTo(point);
}
}
}
)}})
Once you have the latitude and longitude from your form, you do something like this (using your above code as a starting point, for the sake of clarity):
var latlng = new google.maps.LatLng(latitudeFromForm,longitudeFromForm);
// This is creating a GeocoderRequest object
var geocoderRequest = {
'latlng':latlng
}
// This is making the Geocode request
geocoder.geocode(geocoderRequest, function(results, status) {
// This checks to see if the Status is 'OK 'before proceeding
if (status == google.maps.GeocoderStatus.OK) {
// Do stuff with the result here
}
If you haven't read it yet, you may want to read the Reverse Geocoding section of http://code.google.com/apis/maps/documentation/javascript/services.html#ReverseGeocoding.

Youtube javascript api, pjax, how to reload onYouTubeIframeAPIReady();

I have a problem with the youtube javascript player api.
I call this js code :
function onYouTubeIframeAPIReady() {
var podcast = document.getElementById('podcast')
var player = new YT.Player( document.getElementById('podcast'));
player.addEventListener('onStateChange', function(e) {
if (e.data === 1) {
alert("play");
}
});
};
with this html code :
<iframe id="podcast" type="text/html" width="720" height="405"
src="https://www.youtube.com/embed/XXXXXX?cc_load_policy=1&enablejsapi=1&theme=light"
frameborder="0" allowfullscreen>
The problem is that I use the pjax system, so the global javascript code is not reloaded when I navigate.
So, I reload some part of my javascript code when pjax:success. I tried something like this :
$(document).on('pjax:success', function() {
onYouTubeIframeAPIReady();
}
but it doesn't work. My question is how to reload onYouTubeIframeAPIReady(); when it must to be defined globally as it is said there onYouTubeIframeAPIReady function is not calling
When my player is defined I don't use onYoutubePlayerAPIReady. It's the best solution I find, and it works.
var player = {
playVideo: function(container, videoId) {
if (typeof(YT) == 'undefined' || typeof(YT.Player) == 'undefined') {
window.onYouTubePlayerAPIReady = function() {
player.loadPlayer(container, videoId);
};
$.getScript('//www.youtube.com/player_api');
} else {
player.loadPlayer(container, videoId);
}
},
loadPlayer: function(container, videoId) {
window.myPlayer = new YT.Player(container,
height: 200,
width: 200,
videoId: videoId,
});
}
};
var containerId = 'podcast';
var videoId = '<%= #youtube_id %>';
player.playVideo(containerId, videoId);