First of all, everything will be greatly simplified if you can get the identifier on the afamets themselves, for example:
<span class="soundcloud_embed"> <iframe width="100%" height="166" scrolling="no" frameborder="no" src="https://w.soundcloud.com/player/url=http%3A%2F%2Fapi.soundcloud.com%2Ftracks%2F4997623" id="sound1"></iframe> </span> <span class="soundcloud_embed"> <iframe width="100%" height="166" scrolling="no" frameborder="no" src="https://w.soundcloud.com/player/url=http%3A%2F%2Fapi.soundcloud.com%2Ftracks%2F105153133" id="sound2"></iframe> </span> <span class="youtube_embed"> <iframe width="400" height="225" src="//www.youtube.com/embed/tv8WgLEIPBg" id="vid1" frameborder="0" allowfullscreen></iframe> </span> <span class="youtube_embed"> <iframe width="400" height="225" src="//www.youtube.com/embed/FmICU1gMAAw" id="vid2" frameborder="0" allowfullscreen></iframe> </span>
If you prefer not to crack the auto_html pearls that you mentioned to get identifiers, you can use the jquery .uniqueId() function to generate them on all iframes or use the getFrameID() helper method from the message you (and it seems to be already using) .
To make it as simple as possible so that both APIs (Youtube and Soundcloud) can respond to each other's events, you can use several control objects that track which players are on your page and which of them are currently playing (this strategy is similar the one that is used in the links to which you referred, but is expanded to be able to track which player belongs to that API). Use it to define a common pause function, which serves as a simplified wrapper for both APIs:
var playerCurrentlyPlaying = {"api":null,"frameID":null}; var players = {"yt":{},"sc":{}}; pauseCurrentPlayer=function() { var api=playerCurrentlyPlaying["api"], frameid=playerCurrentlyPlaying["frameID"]; switch(api) { case "yt": players[api][frameid].pauseVideo(); break; case "sc": players[api][frameid]["widget"].pause(); break; } };
Next, you need to define two separate functions; the first will be called whenever a YouTube play event is recorded, and the second each time a Soundcloud playback event is captured. Soundcloud HTML5 Widget currently contains several bugs that force some pretty ugly hacks to be included - namely, the Play event sometimes doesn't fire when you first play Soundcloud sound. Fortunately, the Play_Progress event, so we can use this, but we must also include a workaround so that it does not create race conditions when the sound is paused and the video starts:
onYTPlay =function(frameid) { if (playerCurrentlyPlaying["frameID"]!=frameid && playerCurrentlyPlaying["frameID"]!=null) { pauseCurrentPlayer(); } playerCurrentlyPlaying["api"]="yt"; playerCurrentlyPlaying["frameID"]=frameid; }; onSCPlay=function(frameid,event) { if (event==SC.Widget.Events.PLAY||players["sc"][frameid]["firstplay"]==true) { if (playerCurrentlyPlaying["api"]=="yt") { // because any soundcloud player will be automatically paused by another soundcloud event, we only have to worry if the currently active player is Youtube pauseCurrentPlayer(); } playerCurrentlyPlaying["api"]="sc"; playerCurrentlyPlaying["frameID"]=frameid; players["sc"][frameid]["firstplay"]=false; } };
Finally, you can add your hooks to Youtube and insert Soundcloud, remembering the hack we need to make to the Soundcloud Play event. Remember to insert the Soundcloud Widget API ( <script src="w.soundcloud.com/player/api.js"; type="text/javascript"></script> ) and then use this code to bind:
var tag = document.createElement('script'); tag.src = "https://www.youtube.com/iframe_api"; var firstScriptTag = document.getElementsByTagName('script')[0]; firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); function onYouTubeIframeAPIReady() { $(".youtube_embed iframe").each(function() { players["yt"][$(this).attr('id')] = new YT.Player($(this).attr('id'), { events: { 'onStateChange': onYTPlayerStateChange } }); }); } onYTPlayerStateChange = function(event) { if (event.data==YT.PlayerState.PLAYING) { onYTPlay(event.target.a.id); } }; (function(){ $(".soundcloud_embed iframe").each(function() { var frameid=$(this).attr('id'); players["sc"][frameid]={}; players["sc"][frameid]={"widget":SC.Widget(document.getElementById(frameid)),"firstplay":true}; players["sc"][frameid]["widget"].bind(SC.Widget.Events.READY, function() { players["sc"][frameid]["widget"].bind(SC.Widget.Events.PLAY, function() { onSCPlay(frameid,SC.Widget.Events.PLAY); }); players["sc"][frameid]["widget"].bind(SC.Widget.Events.PLAY_PROGRESS, function() { onSCPlay(frameid,SC.Widget.Events.PLAY_PROGRESS); }); }); }); }());
This approach is configured to handle multiple players of both APIs and should be extensible enough if you want to support other embedded multimedia widgets (provided that they expose an event when they start playing and they have the ability to programmatically pause players).