Changing songs on jPlayer by clicking a link, hosted on Amazon S3 - ruby-on-rails

Hello all and thanks for any help in advance.
I have a ruby on rails application in which I am attempting to stream audio through jPlayer, which is hosted on S3. So far I have no problem uploading files or using the browsers built in player to play audio files, or even getting jPlayer to initialize with a song that is on S3. The issue comes when I get into changing songs.
I initialize jPlayer like this:
$('a.html5').click(function() {
var url = $(this).attr('href');
$("#jquery_jplayer_1").jPlayer({
ready: function (event) {
$(this).jPlayer("setMedia", {
mp3: url
});
},
swfPath: "javascripts",
supplied: "mp3",
wmode: "window"
});
return false;
});
where the mp3: url points to the S3 URL (this all works just fine).
This allows me to select a song from a list of links, and it loads up and starts playing no problem.
The issue is that when I try to change songs, I get an access-control-allow-origin error. So I tried the following:
$('a.html5').click(function() {
var url = $(this).attr('href');
$("#jquery_jplayer_1").jPlayer("setMedia", mp3: url).jPlayer("play");
return false;
});
This still gives me an access-control-allow-origin error. I have been pounding my head against the wall for hours trying to figure this out and nothing.
So basically a summary is that I can initialize jPlayer and play a song just fine, but when I want to go change a song, access-control-allow-origin errors ruin my day.
Any ideas?

Well it appears that the only issue was a lack of brackets around the mp3: url part of jPlayer("setMedia"....
so it should have been (...).jPlayer("setMedia", {mp3: url}).(...)

After Searching a lot it could be one of the solutions too.
function songs(json1) {
$("#jquery_jplayer_1").jPlayer("destroy"); //this will destroy previous jplayer content and then if you again call this function it will add the new url of you audio song to the jplayer
var audio_url_inside = json1.audio_url;
$('#jquery_jplayer_1').jPlayer({
ready:function (event) {
$(this).jPlayer("setMedia", {
mp3:audio_url_inside,
oga:audio_url_inside
}).jPlayer("play"); //attemp to play media
},
swfPath:"http://www.jplayer.org/2.1.0/js",
supplied:"mp3, oga"
});
}
:Hope it will help.

Related

Youtube v3 playlistItems.insert api returns Video not found 404 error but video was published in the correct playlist

Seems like Youtube v3 playlist item insertion API (https://developers.google.com/youtube/v3/docs/playlistItems/insert) is responding with a wrong error message even though the video is successfully inserted into the playlist.
I went through the documentation and also searched for similar issues but have no clue why the youtube.playlistItems.insert call is failing.
I'm using googleapis node client to make this request. Here goes the code snippet:
let oauthConfig = config.oauthConfig;
let oAuthClient = new Google.auth.OAuth2(oauthConfig.clientId, oauthConfig.clientSecret);
oAuthClient.setCredentials({access_token: credentials.accessToken, refresh_token: credentials.refreshToken});
let youtubeApi = Google.youtube({version: 'v3', auth: _getOauthClient(_channel.credentials)});
youtube.playlistItems.insert({
part: 'snippet',
resource: {
snippet: {
playlistId: playlist.id,
resourceId: {
kind: 'youtube#video',
videoId: video.id
}
}
}
}, function (err) {
});
Here the callback method receives
404 Video not found.
at Request._callback (<proj_dir>/node_modules/google-auth-library/lib/transporters.js:85:15)
at Request.self.callback (<proj_dir>//node_modules/google-auth-library/node_modules/request/request.js:187:22)
The doc mentioned above says,
notFound (404) - videoNotFound - The video that you are trying to add to the playlist cannot be found. Check the value of the videoId property to ensure that it is correct.
Calling the above code with playlist: PL4D56EB46ED904B8A and video: 4HlpCEEwdxk has resulted in this error, but both video and playlist has public visibility and seems correct. More surprisingly the video uploaded correctly and was inserted into the correct playlist (I verified by visiting https://studio.youtube.com/video/4HlpCEEwdxk/edit/basic), so it seems like a false error.
The same code works for different video without any error though. I'm clueless about what is wrong here. Any help is much appreciated. Thanks

YouTube API and cross origin requests

Has YouTube started locking down cross origin requests?
I am using a fullscreen autoplay hero video on my website and it has been functioning correctly for a long time. Within the last couple weeks it stopped working and I have the following error in the logs.
Failed to execute 'postMessage' on 'DOMWindow': The target origin provided ('https://www.youtube.com') does not match the recipient window's origin ('https://tbrogames.github.io').
Per the answer on this question
I tried changing the host between http and https to see if that would fix it and it didn't.
My website that throws the error: https://tbrogames.github.io/
I was able to find a bigger games website that also has this exact issue.
https://playbattlegrounds.com/main.pu
They are also using a youtube video as the hero/splash video; and it no longer functions, throwing the same error.
The relevant javascript can be found here
https://github.com/tbrogames/tbrogames.github.io/blob/master/js/defer.js
However, this was working for a long time and I didn't change any of the code. Which is why I'm thinking that it is a change that YouTube has made.
I think that error is actually misleading. I had the same issue, but I believe that it is actually chrome that is no longer autoplaying the hero. I get this error: Uncaught (in promise) DOMException: play() failed because the user didn't interact with the document first. https://developers.google.com/web/updates/2017/09/autoplay-policy-changes
The fix for me was calling mute on the video in Javascript Before playing the video. The iframe version of the embed with the same properties would not autoplay
<script>
// 2. This code loads the IFrame Player 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);
// 3. This function creates an <iframe> (and YouTube player)
// after the API code downloads.
var player;
function onYouTubeIframeAPIReady() {
player = new YT.Player('ythero', {
videoId: '3FjTef9gn3Q',
height: '100%',
width: '100%',
playerVars: {
rel: 0,
controls: 0,
showinfo: 0,
autoplay: 1,
loop: 1,
playlist: '3FjTef9gn3Q',
modestbranding: 1
},
events: {
'onReady': onPlayerReady,
}
});
}
// 4. The API will call this function when the video player is ready.
function onPlayerReady(event) {
event.target.mute();
event.target.playVideo();
}
</script>
YouTube does allow it. Make sure you are loading from a URL such as:
https://www.youtube.com/embed/HIbAz29L-FA?modestbranding=1&playsinline=0&showinfo=0&enablejsapi=1&origin=https%3A%2F%2Fintercoin.org&widgetid=1
Note the "origin" component, as well as "enablejsapi=1". The origin must match what your domain is, and then it will be whitelisted and work.

PhoneGap InAppBrowser: open iOS Safari Browser

In our PhoneGap iOS application, we are using the InAppBrowser plugin to display some content, and we need to open a page in Safari from within the InAppBrowser.
How can we have links from within the InAppBrowser open in Safari?
From the phonegap documentation:
Opens a URL in a new InAppBrowser instance, the current browser instance, or the system browser.
var ref = window.open(url, target, options);
ref: Reference to the InAppBrowser window. (InAppBrowser)
url: The URL to load (String). Call encodeURI() on this if the URL contains Unicode characters.
target: The target in which to load the URL, an optional parameter that defaults to _self. (String)
_self: Opens in the Cordova WebView if the URL is in the white list, otherwise it opens in the InAppBrowser.
_blank: Opens in the InAppBrowser.
_system: Opens in the system's web browser.
So to answer your question, use:
window.open(your_url, '_system', opts);
Note that the domain will need to be white-listed.
Update 4/25/2014:
I think I kind of misunderstood the question (thanks to commenter #peteorpeter) -- you want to have some way to click a link in the InAppBrowser and have that open in the system browser (e.g. Mobile Safari on iOS). This is possible, but it will require some forethought and cooperation between the app developer and the person responsible for the links on the page.
When you create an IAB instance, you get a reference to it back:
var ref = window.open('http://foo.com', '_blank', {...});
You can register a few event listeners on that reference:
ref.addEventListener('loadStart', function(event){ ... });
This particular event is fired every time the URL of the IAB changes (e.g. a link is clicked, the server returns a 302, etc...), and you can inspect the new URL.
To break out into the system browser, you need some sort of flag defined in the URL. You could do any number of things, but for this example let's assume there's a systemBrowser flag in the url:
.....html?foo=1&systemBrowser=true
You'll look for that flag in your event handler, and when found, kick out to the system browser:
ref.addEventListener('loadStart', function(event){
if (event.url.indexOf('systemBrowser') > 0){
window.open(event.url, '_system', null);
}
});
Note that this is not the best method for detecting the flag in the url (could lead to false positives, possibly) and I'm pretty sure that PhoneGap whitelist rules will still apply.
Unfortunately target=_system does not work from within the InAppBrowser. (This would work if the link originated in the parent app, though.)
You could add an event listener to the IAB and sniff for a particular url pattern, as you mention in your comments, if that fit your use case.
iab.addEventListener('loadstart', function(event) {
if (event.url.indexOf("openinSafari") != -1) {
window.open(event.url, '_system');
}
}
The 'event' here is not a real browser event - it is a construct of the IAB plugin - and doesn't support event.preventDefault(), so the IAB will also load the url (in addition to Safari). You might try to handle that event within the IAB, with something like:
iab.addEventListener('loadstop', function(event) {
iab.executeScript('functionThatPreventsOpenInSafariLinksFromGoingAnywhere');
}
...which I have not tested.
This message is for clarification:
If you open an another with window.open by catching a link on loadstart, it will kill yor eventhandlers that assigned to first IAB.
For example,
iab = window.open('http://example.com', '_blank', 'location=no,hardwareback=yes,toolbar=no');
iab.addEventListener('loadstop', function(event) {console.log('stop: ' + event.url);});
iab.addEventListener('loaderror', function(event) { console.log('loaderror: ' + event.message); });
iab.addEventListener('loadstart', function(event) {
if (event.url.indexOf("twitter") != -1){
var ref2 = window.open(event.url, '_system', null);
}
});
When the second window.open executed, it will kill all the event listeners that you binded before. Also loadstop event will not be fired after that window.open executed.
I'm finding another way to avoid but nothing found yet..
window.open() doesn't work for me from within an InAppBrowser, whether or not I add a script reference to cordova.js to get support for window.open(...'_system'), so I came up with the following solution which tunnels the "external" URL back to the IAB host through the hashtag so it can be opened there.
Inside the InAppBrowser instance (I'm using AngularJS, but you can replace angular.element with jQuery or $ if you're using jQuery):
angular.element(document).find('a').on('click', function(e) {
var targetUrl = angular.element(this).attr('href');
if(targetUrl.indexOf('http') === 0) {
e.preventDefault();
window.open('#' + targetUrl);
}
});
Note that that's the native window.open above, not cordova.js's window.open. Also, the handler code assumes that all URLs that start with http should be externally loaded. You can change the filter as you like to allow some URLs to be loaded in the IAB and others in Safari.
Then, in the code from the parent that created the InAppBrowser:
inAppBrowser.addEventListener('loadstart', function(e) {
if(e.url.indexOf('#') > 0) {
var tunneledUrl = e.url.substring(e.url.indexOf('#') + 1);
window.open(tunneledUrl, '_system', null);
}
});
With this solution the IAB remains on the original page and doesn't trigger a back-navigation arrow to appear, and the loadstart handler is able to open the requested URL in Safari.

trigger.io - Embed external website

I would like to embed an external website in my app, so I tried it with the tag here:
<iframe src="http://www.uniteich.at" frameborder="0" width="420" height="315"></iframe>
But I get the following error: "Unsafe JavaScript attempt to access frame with URL content://io.trigger.forge2dd999d0f14b11e1bc8612313d1adcbe/src/index.html from frame with URL http://www.uniteich.at/. Domains, protocols and ports must match."
So is there a good solution to embed a website in ios/android app with trigger.io?
Thanks in advance,
enne
EDIT: Ok, to make it more clear what I want: I would just like to load an external website as soon as a user clicks on a specific tabbar button at the bottom. I made this event-handler:
var dessertButton = forge.tabbar.addButton({
text: "Uniteich",
icon: "img/strawberry.png",
index: 2
}, function (button) {
button.onPressed.addListener(function () {
//LOAD EXTERNAL WEBSITE IN CONTENT CONTAINER HERE
});
});
Is that possible somehow?
This issue is cross domain requests. For more information read the same origin policy.
To get around this you will need to utilize forge.request. After adding www.uniteich.at to your config permissions first try the simple forge.get like this:
button.onPressed.addListener(function () {
var mainElement = document.getElementById("main");
forge.request.get("http://www.uniteich.at/index.html", function(content) {
mainElement.innerHTML = content;
},
function(error) {
mainElement.innerHTML = "<b>Error</b>" + error.message;
});
});
And if that does not work or not enough (I am not at my dev computer right now) you can utilize more options with forge.request.ajax.

Fancybox youtube

I am trying to get a fancybox YouTube video to start about 12 minutes into a video. Can someone help me with achieving this? No matter what I have tried, since I am a novice, I cannot get the video to start where I want it to.
I assume that you have already managed to display the video in fancybox and you just you want to select the start time at 12 minutes, don't you?
If so, in the URL of the youtube video just add at the end #t=12m00s (time in minutes and seconds) like
http://www.youtube.com/watch?v=JaFVr_cJJIY#t=12m00s
you could also use this format
http://www.youtube.com/v/JaFVr_cJJIY&autoplay=1#t=12m00s
If you're using the latest version of Fancybox (2+), YouTube and Vimeo are now recognized and handled quite well.
However, it took some digging around to find this out since most documentation is on Fancybox 1.
Fancybox strips your YouTube URL and adds some default parameters:
autoplay=1 (videos will autoplay)
autohide=1 (control will hide once video is playing)
fs=1 (fullscreen is enabled)
rel=0 (related videos are hidden)
hd=1 (HD playback is enabled)
wmode=opaque (fixes z-index with YouTube and lightboxes)
enablejsapi=1 (enables Javascript API)
What this means that normally you could pass those parameters in your URL and have them apply, but Fancybox 2 ignores those and falls back on the preset values.
Don't dismay! You can override those in your script. Several ways.
Normal media embed:
$(".fancybox").fancybox({
helpers : {
media: true
}
});
Custom URL parameters method 1:
$(".fancybox").fancybox({
helpers : {
media: {
youtube : {
params : {
autoplay : 0
}
}
}
}
});
Custom URL parameters method 2:
$(".fancybox").fancybox({,
helpers : {
media: true
},
youtube : {
autoplay: 0
}
});
For your issue, you want to pass in this parameter:
$(".fancybox").fancybox({,
helpers : {
media: true
},
youtube : {
start: 720
}
});

Resources