2016-04-28 36 views
0

我正在構建一個java程序,該程序可以在嵌入式播放器中播放YouTube視頻。 問題是,大多數音樂視頻都不會播放,並且出現以下錯誤: 「此視頻包含(媒體公司名稱)的內容,它在某些網站上播放受到限制。如何解決YouTube API嵌入其他網站的限制問題?

enter image description here

我試圖加載在Chrome相同的URL,並得到了相同的結果。 https://www.youtube.com/embed/TMZi25Pq3T8

然而,一些研究之後,我很快就固定它通過安裝一個Chrome擴展,讓我增加HTTP請求頭,並增加了的Referer頭遵循此結構「https://www..com」,並得到了它的工作。

enter image description here

所以我想那一定是它。

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

儘管如此,沒有成功,同樣的錯誤信息: 我爲了請求頭添加到我的的JavaFX的WebView/WebEngine添加以下代碼。

我用來通過API提取有關發佈的數據的網站Discogs也能夠播放「受限制」的視頻。我在這裏錯過了什麼?

以後編輯: 進一步澄清:

我想爲我所犯的錯誤道歉:

  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. 正如Roman Nazarenko指出的那樣,我將cookies與請求頭混淆在一起。

這導致了一個真正的問題,我如何發送JavaFX WebEngine的HTTP請求標頭?唯一的選擇是通過調用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

我設法通過使用javassistthis tutorial關於如何儀器 Java代碼來解決問題。

正如我在我的問題中所述,YouTube播放器需要一個Referer標題才能播放一些視頻(如VEVO擁有的音樂視頻,Sony Music Enternatinment等)。

我做什麼是我截取prepareConnection方法從所使用的JavaFX的WebEngine並插入我的指示在方法體的頂部的URLLoader類:

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」 訪問方法的參數,而不是 「C」:

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 ,你可以添加像這樣的虛擬機參數:

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

我希望這可以幫助那裏的人。我知道我在這個問題上花了幾天時間。 我不知道這是否是最好的方法,但它爲我做的工作。 儘管如此,它使我不知道爲什麼沒有設置請求頭爲JavaFX的WebEngine的簡單方法...

後來編輯:

我發現一個更清潔容易方法用於加載Java代理,動態,無需創建單獨的JAR,清單文件,導入它們,在啓動時傳遞-javaagent VM參數等。

我使用了ea-agent-loaderJAR download link)。

導入在IDE中的JAR和改變MyJavaAgent類(一個具有的premain方法),以這樣的:從MainClass

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

主要方法看起來是這樣的:

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

我希望能夠動態加載代理,因爲使用靜態方法需要我爲所有平臺創建單獨的啓動器並通過-javaagent參數ameter啓動。現在,我可以像eclipse一樣從eclipse中導出一個可運行的JAR,代理將自動加載(不需要虛擬機參數)。 謝謝,BioWare的這個工具!:D