2013-08-08 20 views
7

Ich habe einen Musikblog, der verschiedene eingebettete Soundcloud- und Youtube-Player enthält.Pause Youtube beim Einbetten einbetten Soundcloud einbetten

Ich möchte verhindern, dass Audio gleichzeitig abgespielt wird. Mit anderen Worten, während ich ein Youtube-Video spiele, wenn ich klicke, um die Soundcloud einzubetten, möchte ich, dass der Youtube-Player pausiert und umgekehrt.

Ich habe einen Code entwickelt, der den Streaming-Youtube-Player unterbricht, wenn ich auf einen anderen Youtube-Player klicke (Soundcloud tut das bereits inhärent). Ich muss es nur kompatibel machen. Würde mich über Hilfe freuen, danke.

var playerCurrentlyPlaying = null; 
var players = {} 
YT_ready(function() { 
    $(".youtube_embed").each(function() { 
     var identifier = this.id; 
     var frameID = getFrameID(identifier); 
     if (frameID) { 
      players[frameID] = new YT.Player(frameID, { 
       events: { 
        "onStateChange": function(event){ 
         if (event.data == YT.PlayerState.PLAYING) 
         { 
          if(playerCurrentlyPlaying != null && 
           playerCurrentlyPlaying != frameID) 
          callPlayer(playerCurrentlyPlaying , 'pauseVideo'); 
          playerCurrentlyPlaying = frameID; 
         } 
        } 
       } 
      }); 
     } 
    }); 
}); 

I Funktionen haben aus diesen Quellen verwendet: Listening for Youtube Event in JavaScript or jQuery

YouTube iframe API: how do I control a iframe player that's already in the HTML?

YouTube API Target (multiple) existing iframe(s)

Rendered mit HTML UniqueID():

<span class="soundcloud_embed" id="soundcloud_post_312"> 
    <iframe id="ui-id-1" width="100%" height="166" scrolling="no" frameborder="no" src="https://w.soundcloud.com/player/?url=http%3A%2F%2Fapi.soundcloud.com%2Ftracks%2F103518792&show_artwork=true&secret_token=s-LnOTK"></iframe> 
</span> 

<span class="youtube_embed" id="youtube_post_309"> 
    <iframe id="ui-id-2" width="528" height="190" src="//www.youtube.com/embed/Y3CYKXBEtf0" frameborder="0" allowfullscreen></iframe> 
</span> 

Antwort

5

Zunächst einmal spielen, wird es stark vereinfacht werden, wenn Sie in der Lage sind, sich eine ID auf die iframes zu bekommen, wie folgt aus:

<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> 

Wenn Wenn Sie das von Ihnen erwähnte Juwel auto_html nicht hacken möchten, um IDs zu erhalten, können Sie entweder die .uniqueId() Funktion von jquery verwenden, um sie auf allen iframes zu generieren, oder die Hilfsmethode getFrameID() aus dem Beitrag, auf den Sie sich beziehen verwenden).

Um die beiden APIs (Youtube und Soundcloud) so einfach wie möglich zu machen, um auf die Ereignisse der anderen reagieren zu können, können Sie einige Kontrollobjekte verwenden, die verfolgen, welche Spieler sich auf Ihrer Seite befinden welche von ihnen gerade gespielt wird (diese Strategie ist ähnlich zu der, die von den Links verwendet wird, auf die Sie sich bezogen haben, aber erweitert werden, um zu verfolgen, welcher Spieler zu welcher API gehört). Damit definieren eine generische Pause-Funktion, die für beide APIs als simpel Wrapper dient:

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; 
    } 
}; 

Als Nächstes werden Sie wollen zwei separate Funktionen definieren; Das erste wird jedes Mal aufgerufen, wenn ein YouTube-Wiedergabeereignis erfasst wird, und das zweite, wenn ein Soundcloud-Wiedergabeereignis erfasst wird. Momentan hat das Soundcloud HTML5 Widget ein paar Bugs, die die Notwendigkeit beinhalten, einige ziemlich hässliche Hacks einzubauen - nämlich, dass das Play Event manchmal nicht ausgelöst wird, wenn Sie einen Soundcloud Sound zum ersten Mal abspielen. Zum Glück ist das Play_Progress Ereignis, so können wir das nutzen, sondern muss auch eine Abhilfe enthalten, damit es nicht eine Race-Bedingung erstellen, wenn ein Geräusch und Starten eines Video-Pause:

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; 
    } 
}; 

Schließlich können Sie dann hinzufügen Ihre Hooks zum Youtube bettet ein und die Soundcloud bettet ein und erinnert sich an den Hack, den wir für das Soundcloud Play Event einsetzen müssen.Vergessen Sie nicht, die Soundcloud Widget API (<script src="w.soundcloud.com/player/api.js"; type="text/javascript"></script>), einbetten und dann diesen Code verwenden, um Ihre Bindungen zu tun:

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); 
     }); 
    }); 
    }); 
    }()); 

Dieser Ansatz eingerichtet ist, um mehrere Spieler beiden APIs zu umgehen und soll anständig erweiterbar, wenn Sie möchten andere einbettbare Medien-Widgets unterstützen (vorausgesetzt, sie zeigen ein Ereignis an, wenn sie zu spielen beginnen und sie haben die Möglichkeit, Spieler programmgesteuert anzuhalten).

+1

Erstens, Vielen Dank für Ihre Zeit und diese fantastische schreiben. Bitte sehen Sie sich meinen aktualisierten Bereich an. Ich bin nicht sicher, ob diese Zeile in der Pause-Funktion funktioniert: players [api] [frameID] .pauseVideo() ;. Wenn ich die Funktion wieder mit dem Callplayer ersetze, hatte ich vorher die YTs als orginal – Jaqx

+0

Ich frage mich, ob es einen Tippfehler oder ein anderes Problem irgendwo anders in Ihrem Code ... wenn ich Ihre fertige Funktion anstelle der, die ich angeboten habe (wo ich die Rückrufe in ihre eigenen Funktionen extrapoliert hatte, anstatt sie einzubetten), aber ich behielt alles andere gleich, die YT-Spieler pausierten immer noch richtig mit der Funktion pauseCurrentPlayer(). Erhalten Sie irgendwelche Konsolenfehler? – jlmcdonald

+0

Beachten Sie auch, dass Sie, wenn Sie die getFrameId- und callplayer-Hilfsfunktionen verwenden, diese ändern müssen, um auch mit soundcloud arbeiten zu können, da sie reguläre Ausdrücke verwenden, um sie YT-spezifisch zu machen (daher habe ich zuerst gesagt) Es war einfacher, die Hilfsfunktionen ganz zu ignorieren und IDs einfach in Ihre iframes einzufügen oder sie mit der Funktion .uniqueID() von jQuery hinzuzufügen, bevor Sie irgendeinen anderen Code ausführen. – jlmcdonald

0

es Mög ble. Überprüfen Sie Widget Api Spielplatz. Sie können alle Statusereignisse von SoundCloud iFrame-Widget überwachen. Dies kann auch über Flash Embed getan werden. https://w.soundcloud.com/player/api_playground.html

Uhr für SC.Widget.Events.PLAY {"loadedProgress":0,"currentPosition":0,"relativePosition":0} Veranstaltung am Start