Background youtube player - google-chrome-extension

I am trying to make a Chrome extension such that to play songs from youtube. I have done this but I have a small problem. When I click the extension icon, a popup appears where I can search the song and play it, but when the popup disappears, the music stops playing. What can I do to make the music play in the background?
Here is the function that finds the song, and inserts iframe tag into my popup.html page
function showResponse(response) {
var responseString = response;
document.getElementById('response').innerHTML = responseString.items[0].id.videoId;
var videoId = responseString.items[0].id.videoId;
var iFrame = '<iframe width="300" height="300" src="https://www.youtube.com/embed/' + videoId + '"></iframe>';
document.getElementById('player').innerHTML = iFrame;
}

When the popup closes, the page that it contains is immediately and completely unloaded.
So your iframe is destroyed. And no, you can't keep the popup open.
An extension has one persistent page - the background page. You can try adding your iframe there - the sound should continue to play.
However, the page is invisible - you can't let the user control the player. Any user-accessible controls will need to be in the popup or some other UI.

Related

The window opened from windows.create isn't scrollable in Firefox

I created in my chrome extension (which because it's a webextension it works in Firefox) a window with
chrome.windows.create(windowobj);
where windowobj is an object with fields like the url, width, height, type='popup' and state='normal'.
When I use it in chrome I can use the new popup window normally, scrolling through the page. However, when I use it in Firefox I can't scroll in the new window. I tried resizing it, still doesn't scroll. When I change state to 'fullscreen' it still doesn't let me scroll.
(I'm using Firefox 59.0, if that makes any difference)
Thanks for your help,
MagnetPlant
I found the bug for this on Bugzilla - https://bugzilla.mozilla.org/show_bug.cgi?id=1331906 - which is still not fixed and the solution found by Techniko was this:
fix.html: (you could easily shorten this if you wanted to)
<script>
var url = new URL(window.location.href);
var parsedUrl = url.searchParams.get('url');
location.href = parsedUrl;
</script>
And then I set the url for a popup window to
windowobj.url = chrome.runtime.getURL('fix.html') + '?url=' + url;
For some reason after redirecting the url through there, the scrolling
in the popup window works normally

Google Analytics Tracking Code Causing Slow Down of Iframe-Resizer?

I have an iframe with dynamic content inside that needs to be displayed on a page and I'd like it to show as quickly as possible. However, there seems to be some lag between when the content of the iframe is loaded and when the iframe is resized on the host page. Currently, the initial dimensions of the iframe are height = 0 and width = 100% so that when the content is loaded in the iframe, iframe-resizer will automatically adjust it to the correct height.
However, I noticed that if there is an autoplay video within the iframe, I can hear the audio for as long as a minute before the iframe will get resized. When checking the browser console, I'll see warning messages of iframe-resizer being unresponsive, but after a minute or so, the iframe will get resized and the content will be revealed.
I have a google analytics tracking code within the iframe content and noticed that if I removed it, the iframe-resizer becomes much more responsive and the content gets loaded quicker. How can I get the iframe to act responsive with the google analytics tracking code running inside of it? How can I get the iframe-resizer to work before the GA script finishes loading?
Also, is setting the initial iframe height to 0 and then allowing iframe-resizer to size the frame the proper way to initially load dynamic iframe content?
edit (adding code):
here's the code i run on the host page
var hzframe = iFrameResize({
checkOrigin: false,
initCallback: function(){
var x = document.getElementsByClassName("hzload");
var i;
for (i = 0; i < x.length; i++) {
x[i].style.display = "none";
}
},
resizedCallback: function() {
var x = document.getElementsByClassName("hzload");
var i;
for (i = 0; i < x.length; i++) {
x[i].style.display = "none";
}
}
},".hzframe");
if you want to see the whole thing in action you can check out this jsfiddle
Currently, I have the same code that hides the loading gif in the initCallback and resizedCallback because the gif doesn't always get hidden by the initCallback.
If your just hosting a video in your iFrame then this might work better for you.
https://css-tricks.com/NetMag/FluidWidthVideo/Article-FluidWidthVideo.php
The issue with GA is very strange, can you defer it running if it is blocking the page load event firing?

YouTube and Fancybox 2

I am able to embed and view my YouTube videos in my website. The problem is: when MY videos finish, a YouTube screen appears with a number of OTHER PEOPLE'S videos as choices. I want the Fancybox pop-up to close when my video finishes so this doesn't happen. I have found a number of suggestions for closing the Fancybox pop-up when a YouTube video ends, but none of them work. I wonder if that's because they're written for Fancybox-1 and I'm using Fancybox-2. I've inserted the code below, but it doesn't trigger.
<script>
function onPlayerStateChange(event){
if (event.data===0){
$.fancybox.close();
}
}
</script>
I do this by adding ?rel=0 to the end of the URL which hides all related videos (more info on rel param here)
You can add ?rel=0 to each of your video URLs (manually), or have the fancybox beforeLoad function add it just before it opens: (example also sets autoplay to 1)
beforeLoad: function () {
var url = $(this.element).attr("href");
url += '?autoplay=1&rel=0';
this.href = url;
}
(Note that this code adds it to all videos and wont work if ? is already in the URL, so you may need to adjust the code to your page)

floating popup.html div

I noticed that the Buffer app for chrome does things a little differently with a floating div when the extension icon is clicked. How is this achieved?
I don't believe they do this in a new window since I am not seeing an addition window being spawned.
Basically what I need is a thickbox to be displayed when the icon is clicked.
Any insight on how this is done would be appreciated.
They're using an api from that background page, to listen to the click event for when the browser action button gets clicked.
Here's a link to that API page:
chrome.browserAction.onClicked.addListener(function(tab) {
chrome.tabs.executeScript(tab.id, {'file': 'createPopup.js'}, function callBackStub(){})
});
createPopup.js
You're html will be in a string. I personally recommend writing this like this:
var widgetHtml =
'<div id="main"> '+
' <p>some stuff goes here</p>'+
'</div>';
Then as your html grows, you can do a column edit of the beginning quote and end '+
Ok, now what you'll want to do is put your html in an iframe, but without setting a src property. Like this:
var iframe = document.createElement('iframe');
document.documentElement.appendChild(iframe); //fastest way to append to DOM: http://jsperf.com/insertbefore-vs-appendchild/2
iframe.contentDocument.body.innerHTML = widgetHtml;
WHY? So your stuff doesn't take on styles from the rest of the page.
Um, and then you can do a translateX or transition left/right position to slide the element into the page.

Spotify App API: tab pages, playlist UI refresh

I am building a Spotify App with four tab pages. The content of all tabs are loaded on initial load of the app. Each tab contain one or more playlists that are being populated with data from 3rd party web apis that are resolved into spotify tracks.
The selected tab works fine. the playlist show up a expected. The problem is with tabs that are initially hidden but later selected. Here the playlist looks like this when selected:
not fully rendered playlist
Looking in the Inspector I can see that the content has not yet rendered:
<div class="sp-list sp-light" tabindex="0">
<div style="height: 100px; ">
</div>
</div>
When I do a resize of the Spotify desktop app, the playlist is finally rendered:
rendered playlist after resize
To populate the playlist I use the 'standard' spotify models and views:
var playlist = new views.List(tempPlaylist);
//where tempPlaylist is a new models.Playlist();
//that has been populated with tempPlaylist.add(search.tracks[0].uri);
playerPlaylistDiv.append(playlist.node);
I am only seing this issue when using tabs. When displaying all content on one long page all playlists are fully rendered. I wonder if it has to do with timing: that I am hiding content that has not yet fully rendered? Any thoughts much appreciated.
I handle tab changes this way:
/* Handle URI arguments */
models.application.observe(models.EVENT.ARGUMENTSCHANGED, tabs);
/* Handle tab changes */
function tabs() {
var args = models.application.arguments;
// Hide all sections
$('section').hide();
// Show current section
$("#" + args[0]).show();
}
FYI I am using the Spotify preview 0.8.10.3.
I am not sure this is the same thing, but I ran into similar issues trying to create tracklistings from playlist-uris on the fly; also couldn't track it down any closer (the containing DOM was certainly rendered and ready); and it only happened on certain playlists, never e.g. on albums.
I was able to circumentvent this problem by "cloning" playlist - obviously there's a "performance" hit ...
// assuming uri is the playlist's URI
models.Playlist.fromURI( uri, function(originalPlaylist) {
var tempPlaylist = new model.Playlist();
$.each(originalPlaylist.tracks, function(t) { tempPlaylist.add(t); });
var tracklist = new views.List(tempPlaylist);
// etc...
}
I am not sure what's on here, but maybe that helps you along :)
PS. Also - make sure you have a doctype-declaration in index.html (), the spotify client does some weird things if you don't.
The solution I've found is this:
I arrowed it down to being an issue with showing/hiding the content since showing the full content without tabs never causes issues. So instead of using .show()/.hide() I now hide and show the content by setting the height of the sections to 100%/0:
// Hide all other sections
$("section#" + args).siblings().height('0');
// Show current section
$("section#" + args).height('100%');
Not sure why this works, but it does (for me at least).
I had the same problem (see Spotify List objects created from localStorage data come up blank) and fixed it by doing the hide()/show() of divs before any processing. Previously I was constructing the playlist and then show()ing the div after which led to a blank list.
I think I've actually managed to solve this and I think it's bulletproof.
Basically I was trying to solve this by trying to convince the API that it needed to redraw the playlist by hiding things/scrolling things/moving things which worked occasionally but never consistently. It never occurred to me to change the playlist itself. Or at least make the API think the playlist has changed.
You can do so by firing an event on the Playlist object.
var models = sp.require('$api/models');
...
// playlist is your Playlist object. Usually retrieved from models.Playlist.fromURI
playlist.notify(models.EVENT.CHANGE, playlist);
These are just standard Spotify functions and the list updates because it thinks something has changed in the playlist. Hope this helps someone!

Resources