- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在构建一个 java 程序,该程序可以选择在嵌入式播放器中播放 YouTube 视频。问题是大多数音乐视频无法播放,并且出现以下错误:“该视频包含来自(媒体公司名称)的内容。该视频被限制在某些网站上播放。”
我尝试在 Chrome 中加载相同的网址并得到相同的结果。 https://www.youtube.com/embed/TMZi25Pq3T8
但是,经过一番研究后,我很快就通过安装一个 Chrome 扩展程序解决了这个问题,该扩展程序允许我添加 HTTP 请求 header ,并添加一个遵循此结构“https://www..com”的 Referer header ,并得到了它工作了。
所以我想一定是这样了。我添加了以下代码,以便将请求 header 添加到我的 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 提取有关版本的数据的网站也能够播放“受限”视频。我在这里缺少什么?
稍后编辑:进一步说明:
我对我所犯的错误表示歉意:
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这引出了真正的问题,如何发送 JavaFX WebEngine 的 HTTP 请求 header ?唯一的选择是通过调用 webView.getEngine().setUserAgent("myUserAgent");
我在这里发现了一个 hack,但这对我不起作用:https://twitter.com/codingfabian/status/524942996748652544
谢谢!
最佳答案
我设法使用javassist解决了这个问题和 this tutorial关于如何检测 Java 代码。
正如我在问题中所述,YouTube 播放器需要Referer header 来播放某些视频(例如 VEVO、Sony Music Enternatinment 等拥有的音乐视频)。
我所做的是拦截 prepareConnection 方法来自 JavaFX 的 WebEngine 使用的 URLLoader 类,并将我的指令插入到方法主体的顶部:
c.setRequestProperty("Referer", "https://www.discogs.com");
(再次,请按照 tutorial 获取所有说明)
(注意:尽管上面的教程很好地解释了概念,但它并没有真正触及 MANIFEST.MF 文件的作用和结构,因此请检查 this link有关这方面的更多信息)
这是我的两个类(class):
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);
}
}
ClassTransformer.java
package com.busytrack.discographymanager.headerfixagent;
import java.io.ByteArrayInputStream;
import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.IllegalClassFormatException;
import java.security.ProtectionDomain;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
public class ClassTransformer implements ClassFileTransformer {
public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
byte[] byteCode = classfileBuffer;
if (className.equals("com/sun/webkit/network/URLLoader")) {
try {
ClassPool classPool = new ClassPool(true);
CtClass ctClass = classPool.makeClass(new ByteArrayInputStream(classfileBuffer));
CtMethod method = ctClass.getDeclaredMethod("prepareConnection");
String src = "$1.setRequestProperty(\"Referer\", \"https://www.discogs.com\");"; // Confused about there being "$1" instead of "c"? Please read below
method.insertBefore(src);
byteCode = ctClass.toBytecode();
ctClass.detach();
} catch (Exception e) {
e.printStackTrace();
}
}
return byteCode;
}
}
这就是为什么我使用“$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 中,您可以像这样添加 VM 参数:
right click on your project -> Run As -> Run Configurations... -> open the Arguments tab -> insert your VM argument -> Apply
我希望这对那里的人有帮助。我知道我在这个问题上花了几天时间。我不知道这是否是最好的方法,但它适合我。尽管如此,这让我想知道为什么没有一种简单的方法来为 JavaFX 的 WebEngine 设置请求 header ...
稍后编辑:
我发现了一种更干净和更简单的方法来动态加载Java代理,而无需创建单独的JAR list 文件、导入它们、启动时传递 -javaagent VM 参数等。
我使用了ea-agent-loader (JAR download link)。
在 IDE 中导入 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 中的 main 方法 如下所示:
public static void main(String[] args) {
AgentLoader.loadAgentClass(MyJavaAgent.class.getName(), null); // Load the MyJavaAgent class
launch(args); // Start the JavaFX application
}
我希望能够动态加载代理,因为使用静态方法需要我为所有平台创建单独的启动器并在启动时传递 -javaagent 参数。现在,我可以像平常一样从 eclipse 导出可运行的 JAR,并且代理将自动加载(不需要 VM 参数)。 感谢 BioWare 提供的这个工具!:D
关于java - 如何像其他网站一样解决 YouTube API 嵌入限制?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36917469/
是否有任何解决方案来禁用右键单击选项并从 Youtube 视频中删除右下角水印 Logo ?我在搜索 GOOGLE 后尝试过。谁能告诉我? 谢谢你。 最佳答案 试试 modestbranding范围:
我想使用 YouTube API (v3) 来启用仅音乐轨道的搜索(没有猫或藤蔓或任何其他非音乐视频)。我查看了 API Explorer 和文档以获取有关该问题的任何指示,但找不到任何有用的信息。
我需要为网站使用YouTube视频缩略图的maxresdefault版本,但是在开发实现此目的的代码后,我发现并非所有视频都具有这些缩略图,尽管这些视频均为1080p。 有没有一种方法可以自动为我的所
我想通过“iframe”嵌入youtube视频,但YouTube在我国禁止使用,建议我如何在我的网站上嵌入视频! [1]:以下图片显示了在我的国家/地区无法访问youtube 最佳答案 该视频将被嵌入
我正在为myBB使用一个名为Profile Music Plugin的插件,可以在此处找到http://community.mybb.com/mods.php?action=view&pid=75 我
Youtube IFRAME API中是否有可以执行命令的功能,例如在播放的视频结尾处打开网站? (我相信有一个功能可以在旧的Java API下执行此操作,但该功能已于去年弃用。) 最佳答案 您可以引
我试图在Videos.insert和Videos.update查询中设置3d尺寸标志。但是标志不会改变。 更新查询示例: 请求: PUT https://www.googleapis.com/yout
使用此获取评论 评论主题:列表 GET https://www.googleapis.com/youtube/v3/commentThreads?part=snippet { "error": {
最近,我尝试使用OEmbed服务通过播放列表查询参数获取视频网址的iframe代码,但是OEmbed为我们提供了与我要求的视频不同的iframe代码。 这是带有播放列表查询参数的视频网址: https
我正在使用此代码: https://www.googleapis.com/youtube/v3/search?q=global+warming&part=id&maxResults=50&key=MY
我有一个LiveBroadcast,并且将来会添加一个scheduledStartTime。据我所知,这次测试不会对LiveBroadcast的整体状态产生影响,即广播是否具有准备就绪/测试的life
YouTube API是否支持在特定时间后关闭浏览器的参数? 这需要使用链接在不同位置共享来推广促销视频。视频播放结束后关闭浏览器。 最佳答案 您可以使用Youtube API监控视频是否播放完毕,然
如果没有表单上的透明面板,YouTube Player将可以正常播放视频,或者可以全屏播放视频,透明面板中有一些图像没有什么特别的。如果我取出透明面板,则YouTube播放器会按需工作,并嵌入到应用程
我正在通过Google进行身份验证,以尝试获取YouTube分析数据,但我的问题是我不知道在查询YouTube时如何向您填充参数 在这里,我正在提供一项新服务:然后尝试查询它 我不确定要在“ids”参
我想添加youtube视频列表,但不添加视频播放器。所以我需要的是 视频标题 视频缩略图 视频时长 我以某种方式设法通过使用此http://img.youtube.com/vi/4wew2uWoARw
我正在使用youtube api和python库gdata 我遵循了文档,但似乎没有出路。 问题是 - How do i get the size of the youtube video fil
使用Youtube API,我如何获得评论或顶过youtube视频的用户ID /处理列表? 提前致谢 最佳答案 在这里,您可以了解如何使用YouTube API v2(v3尚不支持此注释)获取评论:h
我正在为所有相关数据构建一个仪表板(以php为单位),我还想在YouTube“稍后观看”播放列表中显示我的商品数量。 我知道无法使用YouTube API来解决这个问题,但是也许有人想出一种解决方法?
我尝试使用YouTube API,但存在引号问题。 SearchResource.ListRequest searchListRequest = yt.Search.List("sni
我想为我的Android应用程序的用户构建视频推荐器。我有Google OAuth可以登录我的应用程序。我可以获取有关我的应用程序用户在YouTube上观看的视频的数据吗? 最佳答案 v3 API分为
我是一名优秀的程序员,十分优秀!