2016-04-28 5 views
0

Я создаю программу java, которая имеет возможность играть YouTube видео во встроенном проигрывателе. Проблема в том, что большинство музыкальных видеороликов не воспроизводятся, и я получаю следующее сообщение об ошибке: «Это видео содержит контент от (название медиакорпорации). Он ограничен воспроизведением на определенных сайтах».Как я могу обойти ограничения API для API YouTube, как и другие веб-сайты?

enter image description here

Я попытался загружая же URL в Chrome и получили те же результаты. https://www.youtube.com/embed/TMZi25Pq3T8

Однако, после некоторых исследований, я быстро получила ее исправить, установив расширение Chrome, который позволяет мне добавлять HTTP заголовки запросов и добавил Referer заголовка, который следует этой структуре «https://www..com» и получил это работает.

enter image description here

Так что я подумал, что должно быть. Я добавил следующий код, чтобы добавить заголовки запроса на мой JavaFX WebView/WebEngine:

URI uri = URI.create("https://www.youtube.com/embed/TMZi25Pq3T8"); 
List<String> cookies = new ArrayList<>(); 
cookies.add("User-Agent=BDM/v0.92"); 
cookies.add("Referer=https://www.youtube.com"); 
Map<String, List<String>> headers = new LinkedHashMap<String, List<String>>(); 
headers.put("Set-Cookie", cookies); 
try { 
    CookieHandler.getDefault().put(uri, headers); 
} catch (IOException ex) { 
    ex.printStackTrace(); 
} 
System.out.println(webView.getEngine().getUserAgent()); 
webView.getEngine().load(uri.toString()); 

Тем не менее, без успеха, то же сообщение об ошибке.

Веб-сайт, который я использую для извлечения данных об выпусках через их API, Discogs, также может воспроизводить «ограниченные» видео. Что мне здесь не хватает?

СПУСТЯ EDIT: Дальнейшие уточнения:

Я хотел бы извиниться за ошибки, которые я сделал:

  1. Линия System.out.println(webView.getEngine().getUserAgent()); не печатает «BDM/v0.92», как я вначале он печатает пользовательский агент JavaFX по умолчанию, «Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/538.19 (KHTML, например Gecko) JavaFX/8.0 Safari/538.19». И это приводит к числу 2
  2. Как отметил Роман Назаренко, я сбивал с кучей файлы с заголовками запросов.

Это приводит к реальному вопросу, как я могу отправить заголовки HTTP-запросов для JavaFX WebEngine? Единственный вариант для установки агента пользователя по телефону webView.getEngine().setUserAgent("myUserAgent");

Я нашел хак здесь, но это didin't работает для меня: https://twitter.com/codingfabian/status/524942996748652544

Спасибо!

+0

Является ли ошибка, исходящая от вызова API? Если это так, вам может потребоваться проверить, какие параметры вы должны отправлять при отправке запроса. Таким образом, вы сможете определить любой недостающий параметр в случае, если ошибка выдается из API. –

+0

Вы рассказываете о заголовках, но здесь вы настраиваете файлы cookie. Это не одно и то же. –

+0

Вы пробовали прочитать это? http://stackoverflow.com/questions/13407482/youtube-embed-gives-restricted-from-playback-on-certain-sites-error-despite-ap. Кроме того, я нашел этот блог разработчиков и разработчиков YouTube: http://youtube-eng.blogspot.co.uk/2011/12/understanding-playback-restrictions_28.html. Это может помочь вам. –

ответ

2

мне удалось решить эту проблему с помощью javassist и this tutorial о том, как инструмент Java код.

Как я уже сказал в своем вопросе, игроку YouTube необходим Referer header, чтобы воспроизвести некоторые видеоролики (например, музыкальные клипы, принадлежащие VEVO, Sony Music Enternatinment и т. Д.).

То, что я сделал, я перехватил prepareConnection метод из URLLoader класса, который используется WebEngine JavaFX в и вставил свою команду в верхней части тела метода:

c.setRequestProperty("Referer", "https://www.discogs.com"); 

Code from the JDK source files

(Опять же, пожалуйста, следуйте tutorial за все инструкции)

(Примечание: Несмотря на то, учебник выше объясняет очень хорошо понятие, он не тронет много о роли и структуре MANIFEST.MF файла, пожалуйста, проверьте this link для получения дополнительной информации об этом аспекте)

это мои два класса:

MyJavaAgent.java

package com.busytrack.discographymanager.headerfixagent; 
import java.lang.instrument.Instrumentation; 
public class MyJavaAgent { 
public static void premain(String agentArgument, Instrumentation instrumentation) { 
    ClassTransformer transformer = new ClassTransformer(); 
    instrumentation.addTransformer(transformer); 
    } 
} 

ClassTrans former.java

Вот почему я использовал "$ 1", чтобы получить доступ к параметру метода, вместо "с":

The statement and the block can refer to fields and methods. They can also refer to the parameters to the method that they are inserted into if that method was compiled with the -g option (to include a local variable attribute in the class file). Otherwise, they must access the method parameters through the special variables $0, $1, $2, ... described below. Accessing local variables declared in the method is not allowed although declaring a new local variable in the block is allowed.

Весь Javassist учебник можно найти here.

После укладки двух классов и файл MANIFEST.MF в отдельном JAR, импортировать его в IDE (я использовал Eclipse) и добавьте следующий VM аргумент:

-javaagent:./(your-jar-name).jar 

В Eclipse , вы можете добавить аргументы VM следующим образом:

right click on your project -> Run As -> Run Configurations... -> open the Arguments tab -> insert your VM argument -> Apply 

Я надеюсь, что это поможет кому-то там. Я знаю, что провел несколько дней по этому вопросу. Я не знаю, подходит ли это лучший подход, но он выполняет эту работу для меня. Тем не менее, это заставляет меня задаться вопросом, почему не существует простой способ установки заголовков запроса для WebEngine JavaFX в ...

Позже изменения:

Я нашел много очистителя и проще подхода для загрузки Java-агентов, динамически, без необходимости создавать отдельный JAR-файл манифеста, импортировать его, передавая параметр -javaagent VM при запуске и т. д.

Я использовал ea-agent-loader (JAR download link).

Импорт JAR в интегрированную среду и изменить MyJavaAgent класс (тот, который имел метод premain) к этому:

package com.busytrack.discographymanager.headerfixagent; 
import java.lang.instrument.Instrumentation; 
public class MyJavaAgent { 
    public static void agentmain(String agentArgument, Instrumentation instrumentation) { 
     ClassTransformer transformer = new ClassTransformer(); 
     instrumentation.addTransformer(transformer); 
    } 
} 

Мой основной метод из MainClass выглядит следующим образом:

public static void main(String[] args) { 
    AgentLoader.loadAgentClass(MyJavaAgent.class.getName(), null); // Load the MyJavaAgent class 
    launch(args); // Start the JavaFX application 
} 

Я хотел бы иметь возможность загружать Агент динамически, потому что, используя статический метод, мне потребовалось создать отдельные пусковые установки для всех платформ и передать параметр -javaagent par ameter при запуске. Теперь я могу экспортировать исполняемый JAR из eclipse, как я обычно делаю, и агент будет загружаться автоматически (никаких параметров VM не требуется). Спасибо, BioWare для этого инструмента!: D