it-swarm.com.de

Wechseln Sie zwischen Youku und YouTube, je nachdem, ob Sie sich in China befinden

Ich hoste eine Konferenz-Website, auf der ich ein Youku-Video einbetten möchte, wenn Sie sich in China befinden, ansonsten ein YouTube-Video. Die Konferenz-Website wird über ein CDN in der Great Firewall bereitgestellt. Ich habe den folgenden Code erhalten, um zwischen internen und externen Versionen von Youku zu wechseln.

Leider scheint es, dass ipinfo.io nicht innerhalb der Großen Firewall zugänglich ist. Daher tritt der Code nach 10 Sekunden ab.

Ich habe mir überlegt, die Seite so umzuschreiben, dass sie standardmäßig ein Youku-Video verwendet, und eine kleine, nicht blockierende JavaScript-Funktion schreibt, die versucht, YouTube zu erreichen. Wenn es möglich ist, ersetzen Sie das Youku durch YouTube. Wenn dies nicht möglich ist, verlassen Sie das Gerät ohne Probleme. Auf diese Weise wird die Erreichbarkeit von YouTube zum Schlüsseltest, nicht ob Sie in China sind.

Alternativ habe ich mir überlegt, das Video auf meiner Website zu hosten, damit es über das CDN in der Great Firewall repliziert wird. Dies würde jedoch bedeuten, dass das Video immer mit voller Auflösung heruntergeladen wird, selbst wenn Sie eine langsame Verbindung haben.

Gibt es bessere Vorschläge, wie Sie zwischen Youku und Youtube wechseln können, oder generell ein Video haben, das sowohl innerhalb als auch außerhalb Chinas abspielbar ist?

jQuery.get("https://ipinfo.io", function(response) {
    var country = response.country;

    if(country == 'CN') {
        youku.attr('src',chinaVideo)
    } else {
        youku.attr('src',generalVideo)
    }
}, "jsonp");
15
dankohn

Hier ist das JavaScript, mit dem wir gehen:

$(document).ready(function (){
    var country = '',
    youku = $('#youku');

    $.ajax({
        url: "https://ipinfo.io",
        dataType: "jsonp",
        success: function(response){
            var country = response.country;

            if(country != 'CN') {
                youku.attr('src','https://www.youtube.com/embed/K3cEE5h7c1s')
            }
         },
         error: function(){
            console.log('sorry...')
         },
         timeout: 5000
    });     
});

Wir fügen den Youku-Link in den HTML-Code ein und wechseln zu YouTube, wenn das Land nicht China ist. Dies funktioniert immer noch, wenn die Verbindung zu ipinfo.io abgelaufen ist, was manchmal in China der Fall ist.

Bearbeiten: Überarbeitet, um ein Timeout von 5 Sekunden hinzuzufügen.

6
dankohn

Es ist besser, gezielt zu prüfen, ob YouTube im Netzwerk des Nutzers blockiert ist, anstatt ein Land basierend auf IP herauszufiltern. Auf diese Weise funktioniert es sogar in jeder Schul- oder Büroumgebung, in der YouTube aus irgendeinem Grund vom Netzwerkadministrator blockiert werden könnte.

Dies ist die beste Antwort, die ich in dieser Hinsicht finden konnte, die versucht, die favicon von YouTube über JavaScript zu laden. Wenn das kleine Bild heruntergeladen werden kann, ist YouTube verfügbar. Das Bild enthält nur 0,2 Kilobyte Download und wird höchstwahrscheinlich bereits von jedem Nutzer, der YouTube besucht hat, zwischengespeichert.

Das bedeutet, dass das Ergebnis für Nutzer mit YouTube-Zugriff fast sofort ist und für Benutzer mit blockierten Firewalls einige Sekunden dauert. Der Code ist einfach:

jQuery(function(){
    var youku = jQuery('#youku');
    var image = new Image();
    image.onload = function(){
        youku.attr('src','https://www.youtube.com/embed/K3cEE5h7c1s')
    };
    image.onerror = function(){
        youku.attr('src','https://www.youku.com/embed/K3cEE5h7c1s')
    };
    image.src = "https://youtube.com/favicon.ico";
});

Dies ist eine bessere Lösung als oben angegeben, da nicht auf das document.ready-Ereignis von jQuery gewartet wird. Das Bild wird sofort geladen.

(function(){
    var image = new Image();
    image.onload = function(){
        jQuery(function(){
            jQuery('#youku').attr('src','https://www.youtube.com/embed/K3cEE5h7c1s')
        });
    };
    image.onerror = function(){
        jQuery(function(){
            jQuery('#youku').attr('src','https://www.youku.com/embed/K3cEE5h7c1s')
        });
    };
    image.src = "https://youtube.com/favicon.ico";
})();

Update basierend auf Kommentaren:

Falls die Möglichkeit besteht, dass das Bild zuvor auf dem Computer des Benutzers zwischengespeichert wurde, wird durch Hinzufügen des aktuellen Zeitstempelparameters zur Bild-URL sichergestellt, dass das Bild trotz vorheriger Zwischenspeicherung geladen wird.

    image.src = "https://youtube.com/favicon.ico?_=" + Date.now();
3
Munim Munna

Bessere Vorschläge zum Wechseln zwischen Youku und Youtube oder allgemeiner haben ein Video sowohl innerhalb als auch außerhalb Chinas abspielbar?

Ich würde vorschlagen, einen Blick auf Alibaba Cloud zu werfen. Sie haben eine Reihe von Dienstleistungen, aber bei AFAIK gibt es keinen kostenlosen Plan.
Da ich mit anderen Cloud-Anbietern für China nicht vertraut bin, lassen Sie mich eine Lösung für Alibaba Cloud beschreiben.

Ich sehe zwei Möglichkeiten für Sie:

  1. verwenden Sie ihren CDN-Service und erstellen Sie zwei JS-Pakete - eines für China und eines für den Rest der Welt. Das erste Video wird von Youku und das zweite von Youtube eingebettet. Nachdem Sie sie in CDN hochgeladen haben, können Sie sie zwingen, sie an lokale Knoten in China/World zu senden, sodass die Benutzer immer schnell und auf dem neuesten Stand sind.
  2. verwenden Sie ihren Media Transcoding Service für die Videobearbeitung + Object Storage Service für Video-Hosting + CDN-Service zur Verteilung. Auf diese Weise können Sie mehrere Videos unterschiedlicher Qualität erstellen und diese in der Nähe Ihrer Benutzer verteilen. JS wird das Video direkt von CDN einbetten. Für ein Video könnte dies ein Overkill sein.
0

Sie können ffmpeg verwenden, um das Video in eine HLS-Version zu konvertieren. Erstellen Sie die HLS-Wiedergabeliste (.m3u8) von Hand basierend auf RFC 8216. ffmpeg erstellt keine Master-Wiedergabeliste für Sie. HLS hilft bei der Anpassung der Auflösung an die Internetgeschwindigkeit. Wenn Sie dies mit dem kostenlosen Mediaplayer von hls.js javascript kombinieren, können Sie es auf Ihrer eigenen Website hosten, um durch die große Firewall von China zu gelangen, und die adaptive Auflösung unterstützen.

Hier ein Beispiel für eine HLS-Master-Wiedergabeliste, damit Sie nicht unbedingt RFC 8216 lesen müssen. Die Datei heißt Video.m3u8:

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-STREAM-INF:BANDWIDTH=5000000,RESOLUTION=1920x1080
Video_1080p.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=9000000,RESOLUTION=2560x1440
Video_1440p.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=16000000,RESOLUTION=3840x2160
Video_4k.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=2800000,RESOLUTION=1280x720
Video_720p.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=1400000,RESOLUTION=842x480
Video_480p.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=800000,RESOLUTION=640x360
Video_360p.m3u8

Die Bandbreite wird in Bits pro Sekunde angegeben. Die Reihenfolge der Qualität spielt keine Rolle, da der Mediaplayer die Auflösung wählt.

Der Befehl, den Sie für ffmpeg in der Eingabeaufforderung verwenden können, lautet:

ffmpeg -hwaccel dxva2 -hide_banner -y -i "C:\input\Video.mp4" -vf scale=1920:1080 -c:a aac -ar 48000 -c:v h264 -profile:v main -crf 20 -r 30 -sc_threshold 0 -g 48 -keyint_min 48 -hls_time 2 -hls_playlist_type vod -b:v 5000k -maxrate 5350k -bufsize 7500k -b:a 192k -hls_segment_filename "C:\output\Video_1080p_%03d.ts" "C:\output\Video_1080p.m3u8" -vf scale=2560:1440 -c:a aac -ar 48000 -c:v h264 -profile:v main -crf 20 -r 30 -sc_threshold 0 -g 48 -keyint_min 48 -hls_time 2 -hls_playlist_type vod -b:v 9000k -maxrate 10350k -bufsize 14500k -b:a 192k -hls_segment_filename "C:\output\Video_1440p_%03d.ts" "C:\output\Video_1440p.m3u8" -vf scale=3840:2160 -c:a aac -ar 48000 -c:v h264 -profile:v main -crf 20 -r 30 -sc_threshold 0 -g 48 -keyint_min 48 -hls_time 2 -hls_playlist_type vod -b:v 16000k -maxrate 20350k -bufsize 26000k -b:a 192k -hls_segment_filename "C:\output\Video_4k_%03d.ts" "C:\output\Video_4k.m3u8" -vf scale=1280:720 -c:a aac -ar 48000 -c:v h264 -profile:v main -crf 20 -r 30 -sc_threshold 0 -g 48 -keyint_min 48 -hls_time 2 -hls_playlist_type vod -b:v 2800k -maxrate 2996k -bufsize 4200k -b:a 128k -hls_segment_filename "C:\output\Video_720p_%03d.ts" "C:\output\Video_720p.m3u8" -vf scale=842:480 -c:a aac -ar 48000 -c:v h264 -profile:v main -crf 20 -r 30 -sc_threshold 0 -g 48 -keyint_min 48 -hls_time 2 -hls_playlist_type vod -b:v 1400k -maxrate 1498k -bufsize 2100k -b:a 128k -hls_segment_filename "C:\output\Video_480p_%03d.ts" "C:\output\Video_480p.m3u8" -vf scale=640:360 -c:a aac -ar 48000 -c:v h264 -profile:v main -crf 20 -r 30 -sc_threshold 0 -g 48 -keyint_min 48 -hls_time 2 -hls_playlist_type vod -b:v 800k -maxrate 865k -bufsize 1200k -b:a 96k -hls_segment_filename "C:\output\Video_360p_%03d.ts" "C:\output\Video_360p.m3u8"

Sie müssen nur C:\input\Video.mp4 durch Ihr Video ersetzen und alle C:\output\Video durch einen Ausgabenamen für das Video ersetzen. 360p steht für die im Ausgabevideodateinamen angegebene Auflösung. Die tatsächliche Auflösung wird nicht beeinflusst.% 03d ist ein Befehl, der analysiert wird, um dem Videofragment eine Zahl wie 001 bis 999 zu geben. Der Unterstrich wird zur besseren Lesbarkeit verwendet.

Erklärung der Kommentare: - hwaccel dxva2 bedeutet, dass ffmpeg die Hardwarebeschleunigung mithilfe von directx verwendet. Dies ist unter Windows Vista und höher verfügbar. __ hls_time 2 setzt die Fragmentzeit auf 2 Sekunden pro Fragment . Aac und h264 sind die Codecs, die in den hls-Videofragmenten verwendet werden sollen.

Dieser Befehl für ffmpeg generiert 6 Qualitätsstufen, erstellt jedoch keine Master-Playlist. Die Master-Wiedergabeliste ist eine Wiedergabeliste mit Wiedergabeliste pro Bandbreite (siehe oben). Abhängig von der Internetgeschwindigkeit wählt der HSL-Player aus, welche Wiedergabeliste von Videofragmenten wiedergegeben werden soll.

0
Cambesa

Ihre derzeitige Lösung ist nicht ideal, da sie vom Zeitlimit der GET-Anforderung abhängt, was die Dinge verlangsamen wird. Da es sich in der Hauptsache um das Blockieren von ipinfo.io in China handelt, ist es wahrscheinlich, dass eine effektive Lösung einen in China ansässigen IP-Identifikationsdienst beinhalten würde.

Versuchen Sie es mit http://www.ip138.com/. Google Translate funktioniert gut genug, um es auf Englisch zu lesen. Es scheint keine formale JSON-API zu geben, aber Sie können http://www.ip138.com/ips138.asp?ip=<IP_ADDRESS_HERE> drücken und die Standortinformationen abrufen.

Navigieren Sie dazu im DOM mit jQuery (da Sie es bereits verwenden) zur Zeile mit 本站数据:, die vor dem Namen des Landes steht. Ich denke, der Selektor dafür, da die Seite derzeit aufgebaut ist, ist einfach $( "li" ).first(). Extrahieren Sie die Zeichenfolge nach dem Doppelpunkt und dem POST in die Google Translate API, um den Ländernamen in Englisch und voila zu erhalten! Sie haben eine schnellere und zuverlässigere (wenn auch wesentlich kompliziertere) Möglichkeit, zu sehen, ob sich ein Besucher in China aufhält oder nicht.

BEARBEITEN: Es ist nicht ganz klar, ob Sie zuvor die IP-Adresse des Benutzers besitzen. Wenn nicht, können Sie eine ähnliche Methode mit https://geoiptool.com/zh/ verwenden, die ebenfalls in China basiert und daher nicht gesperrt ist. Ich bin glücklich, diesen Teil je nach Bedarf auszuarbeiten.

0
223seneca

Was ist mit der Zeitzone des Kunden? Obwohl dies nicht perfekt ist, können Sie es vermeiden, sich auf Timeouts oder Geoip-Serviceanfragen zu verlassen. Wenn möglich, würde ich eine Vorgehensweise vermeiden, die zu vielen wiederholten Anrufen derselben blockierten Ressource von demselben Adressblock (z. B. von Konferenzteilnehmern) führen könnte. Als ich das letzte Mal in China lebte, erinnere ich mich, dass ich von der Great Firewall TCP) einen Reset ausgelöst habe, der gut 30 Sekunden oder länger dauern würde.

Intl.DateTimeFormat().resolvedOptions().timeZone ist vernünftigerweise gut unterstützt in modernen Browsern. In China sollte die IANA-Zeitzone für China zurückgegeben werden: "Asien/Shanghai":

console.log(Intl.DateTimeFormat().resolvedOptions().timeZone)

Es gibt auch Bibliotheken ( jsTimezoneDetect und moment-timezone ), die das oben Genannte zusammen mit der Funktion getTimezoneOffset von Date über mehrere Punkte in kombinieren time, um die Zeitzone zu erraten, die mit älteren Browsern möglicherweise bessere Ergebnisse liefert:

console.log(jstz.determine().name());
console.log(moment.tz.guess());
<script src="//cdnjs.cloudflare.com/ajax/libs/jstimezonedetect/1.0.6/jstz.min.js"></script>

<script src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment-timezone/0.5.5/moment-timezone-with-data-2010-2020.min.js"></script>

Ich für meinen Teil würde wahrscheinlich versuchen, die Zeitzone als "Asien/Shanghai" zu erkennen und auf einen Zeitzonenversatz von "UTC + 8" zurückzugreifen (Zeitzonenversatz allein wird mehr als Festlandchina erfassen, aber ich würde mir vorstellen, dass dies akzeptabel ist Overreach für eine Fallback-Strategie), zB:

var ianaTz = Intl.DateTimeFormat().resolvedOptions().timeZone;
var offset = new Date().getTimezoneOffset();

if (ianaTz === "Asia/Shanghai" || (ianaTz == null && offset/60 == -8)) {
  console.log("We'll assume China");
} else {
  console.log("not China");
}
0
eddies

LOCALE-INFORMATIONEN VON BROWSERN MIT JAVASCRIPT ERHALTEN

Um den Erkennungsprozess zu beschleunigen, können Sie zunächst versuchen, Informationen zur Ländereinstellung aus der Installationssprache des Browserpakets zu extrahieren:

navigator.language
navigator.languages

und dann kombinieren Sie diese oder, als letzte Ressource, einen Rückfall auf einen geografischen Ort oder auf andere Weise, um die Präferenzen der Benutzersprache aus dem Accept-Language-HTTP-Header zu ermitteln.

Das folgende Beispiel zeigt einen externen Dienst zum Erfassen der Browser-Header:

https://ajaxhttpheaders1.appspot.com/?callback=getHeaders

Ein anderer Pfad, der mit der obigen Lösung kombiniert werden könnte, besteht darin, einige Zeichenfolgen aus der Benutzerumgebung oder dem Browserkontext (window.location, document.cookie, document.localStorage, Date () oder Date (). ToLocaleString () usw.) zu übernehmen und scannen Sie diese Zeichenfolge mit Unicode-Bereichen für reguläre Ausdrücke nach chinesischem Unicode-Codepunkt.

Ich glaube, dies wird Ihnen eine sehr gute Annäherung geben, ohne zusätzliche Anfragen zu stellen. In meinem Firefox-Browser beispielsweise erzeugt ein Aufruf Date().toLocaleString() Folgendes:

"Mon Jul 30 2018 01:35:38 GMT+0200 (Ora legale Dell’Europa centrale)"

das kann einfach als "italienisches" Gebietsschema analysiert werden.

Sie finden irgendwo einen Unicode-Punkt eines chinesischen Ideogramms/Symbols.

0
Diego Perini