Ich versuche herauszufinden, wie Sie ein Video von youtube in das lokale Dateisystem herunterladen. Ich habe ein paar Pakete wie vGet ausprobiert, aber es scheint nicht zu funktionieren. Jede Hilfe wird sehr geschätzt.So laden Sie Youtube Video in Java
Antwort
ich vget habe versucht, https://github.com/axet/vget (bewegt hat https://gitlab.com/axet/vget) und es funktioniert gut. Sie können maven verwenden, um Abhängigkeiten von Pom-Dateien manuell einzurichten oder herunterzuladen. Abhängigkeiten
wget (https://github.com/axet/wget)
Gemeinen-io-2.4.jar
commons lang3-3.1.jar
httpcore-4.3.jar
httpclient-4.3.jar
xstream-1.4.2.jar
mit jdk6 zusammengestellt
als die direkten Download Probe lief ein fertiges Arbeitsbeispiel
public class DirectDownload {
public static void main(String[] args) {
try {
VGet v = new VGet(new URL("http://www.youtube.com/watch?v=fNU4UNPNeWI"), new File("/"));
v.download();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
Check-out, sind Quellen, die in das Glas
zip-Datei - 1,89KB
https://www.wetransfer.com/downloads/465f7ef8c6a76f79e4cbd7c9f38a608c20131005141332/41c09a86ed8eaa6e61f59282eabda2a120131005141332/4ac689
UPDATE # - NPE Problem, wenn in den Kommentaren
TLDR wie erwähnt das Herunterladen; Es scheint ein paar Probleme mit com.github.axet.vget.vhs.YouTubeParser
zu geben, also fügen Sie nicht intrusiven Code hinzu, um es zu patchen und das Beispiel so zu machen, wie es früher war. Ersetzen Sie also einfach die ursprüngliche YoutubeParser
Klasse durch die, die hier am Ende steht.
Finden Sie auch ein anderes funktionsfähiges Beispiel mit jar und allen erforderlichen libs, Quellen sind im jar enthalten (das wird automatisch nach einer gewissen Zeit entfernt (wird am 13. September 2014 gelöscht) - die Youtube URLs enthalten im Code sind zufällig)
Zip-Datei - 1,69MB (wetransfer.com Displays 1,7MB)
A. FRAGEN
In com.github.axet.vget.vhs.YouTubeParser ln229 die Variable
qs
die meisten der Zeit es nicht die resultierende Abfrage-String des http mitWGet
erhalten ausgeführt enthält. Dies führt dazu, dass dienpe
später ausgelöst wird, wenn versucht wird, die Abfragezeichenfolge zu analysieren.Wenn das Problem 1 behoben wird dann die
sig
Variable in den URLs nicht gefunden wird, das von demget_video_info
, so mitPattern.compile("sig=([^&,]*)")
Parsen liefert keine Werte. Dies führt zu kontinuierlichen Wiederholungen, ohne dass das Video heruntergeladen werden muss.
B. BESCHLÜSSE(diese sind temporäre Flecken, wie das ursprüngliche Format der Antwort und die Ursache der WGet abgestürzten nicht bekannt sind)
WGet
erneut aufrufen, wenn die resultierende Abfragezeichenfolge ist leer, ohne dass einWGet.HtmlLoader
die Aufgabe zu erledigen scheint. Es wurde auch ein Ansatz zum Aufrufen eines einfachen HTTP-GET unter Verwendung des Apache-httpclient v4 bereitgestellt, in diesem Fall gibt es eine weitere Abhängigkeit von apache commons-logging.jar.
in ln248 hinzugefügt
if (qs == null || qs.trim().length() == 0) {
qs = WGet.getHtml(url);
////below is sample code for simple HTTP GET with httpclient v4
////if used then apache commons-logging.jar is also required
// CloseableHttpClient httpclient = HttpClients.createDefault();
// try {
// HttpGet httpget = new HttpGet(get);
//
// System.out.println("Executing request " + httpget.getRequestLine());
//
// // Create a custom response handler
// ResponseHandler<String> responseHandler = new ResponseHandler<String>() {
//
// public String handleResponse(
// final HttpResponse response) throws ClientProtocolException, IOException {
// int status = response.getStatusLine().getStatusCode();
// if (status >= 200 && status < 300) {
// HttpEntity entity = response.getEntity();
// return entity != null ? EntityUtils.toString(entity) : null;
// } else {
// throw new ClientProtocolException("Unexpected response status: " + status);
// }
// }
//
// };
// String responseBody = httpclient.execute(httpget, responseHandler);
// qs = responseBody;
// } finally {
// httpclient.close();
// }
}
2.After Blick auf die Antwort gibt die Signatur in einem bestimmten Ort zu sein scheint, so verstärkt das ein bisschen Parsen. Wenn also die Musterausführung von Pattern.compile("sig=([^&,]*)")
nichts zurückgibt, dann versuche auch mit Pattern.compile("signature%3D([^&,%]*)")
. Diese Änderung erfolgte in der Methode extractUrlEncodedVideos
.
String sig = null;
{
Pattern link = Pattern.compile("signature=([^&,]*)");
Matcher linkMatch = link.matcher(urlString);
if (linkMatch.find()) {
sig = linkMatch.group(1);
} else {
link = Pattern.compile("signature%3D([^&,%]*)");
linkMatch = link.matcher(urlString);
if (linkMatch.find()) {
sig = linkMatch.group(1);
}
}
}
Die modifizierte com.github.axet.vget.vhs.YouTubeParser
Datei wird wie folgt
package com.github.axet.vget.vhs;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.lang3.StringEscapeUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.NameValuePair;
import org.apache.http.client.utils.URLEncodedUtils;
import com.github.axet.vget.info.VGetParser;
import com.github.axet.vget.info.VideoInfo;
import com.github.axet.vget.info.VideoInfo.States;
import com.github.axet.vget.info.VideoInfo.VideoQuality;
import com.github.axet.wget.WGet;
import com.github.axet.wget.info.ex.DownloadError;
import java.io.IOException;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
public class YouTubeParser extends VGetParser {
public static class VideoUnavailablePlayer extends DownloadError {
private static final long serialVersionUID = 10905065542230199L;
public VideoUnavailablePlayer() {
super("unavailable-player");
}
}
public static class AgeException extends DownloadError {
private static final long serialVersionUID = 1L;
public AgeException() {
super("Age restriction, account required");
}
}
public static class PrivateVideoException extends DownloadError {
private static final long serialVersionUID = 1L;
public PrivateVideoException() {
super("Private video");
}
public PrivateVideoException(String s) {
super(s);
}
}
public static class EmbeddingDisabled extends DownloadError {
private static final long serialVersionUID = 1L;
public EmbeddingDisabled(String msg) {
super(msg);
}
}
public static class VideoDeleted extends DownloadError {
private static final long serialVersionUID = 1L;
public VideoDeleted(String msg) {
super(msg);
}
}
List<VideoDownload> sNextVideoURL = new ArrayList<VideoDownload>();
URL source;
public YouTubeParser(URL input) {
this.source = input;
}
public static boolean probe(URL url) {
return url.toString().contains("youtube.com");
}
void downloadone(VideoInfo info, AtomicBoolean stop, Runnable notify) throws Exception {
try {
extractEmbedded(info, stop, notify);
} catch (EmbeddingDisabled e) {
streamCpature(info, stop, notify);
}
}
/**
* do not allow to download age restricted videos
*
* @param info
* @param stop
* @param notify
* @throws Exception
*/
void streamCpature(final VideoInfo info, final AtomicBoolean stop, final Runnable notify) throws Exception {
String html;
html = WGet.getHtml(info.getWeb(), new WGet.HtmlLoader() {
@Override
public void notifyRetry(int delay, Throwable e) {
info.setDelay(delay, e);
notify.run();
}
@Override
public void notifyDownloading() {
info.setState(States.DOWNLOADING);
notify.run();
}
@Override
public void notifyMoved() {
info.setState(States.RETRYING);
notify.run();
}
}, stop);
extractHtmlInfo(info, html, stop, notify);
extractIcon(info, html);
}
/**
* Add resolution video for specific youtube link.
*
* @param url download source url
* @throws MalformedURLException
*/
void addVideo(String itag, String url) throws MalformedURLException {
Integer i = Integer.decode(itag);
VideoQuality vd = itagMap.get(i);
URL u = new URL(url);
if (u != null) {
sNextVideoURL.add(new VideoDownload(vd, u));
}
}
// http://en.wikipedia.org/wiki/YouTube#Quality_and_codecs
static final Map<Integer, VideoQuality> itagMap = new HashMap<Integer, VideoInfo.VideoQuality>() {
private static final long serialVersionUID = -6925194111122038477L;
{
put(120, VideoQuality.p720);
put(102, VideoQuality.p720);
put(101, VideoQuality.p360);
put(100, VideoQuality.p360);
put(85, VideoQuality.p520);
put(84, VideoQuality.p720);
put(83, VideoQuality.p240);
put(82, VideoQuality.p360);
put(46, VideoQuality.p1080);
put(45, VideoQuality.p720);
put(44, VideoQuality.p480);
put(43, VideoQuality.p360);
put(38, VideoQuality.p3072);
put(37, VideoQuality.p1080);
put(36, VideoQuality.p240);
put(35, VideoQuality.p480);
put(34, VideoQuality.p360);
put(22, VideoQuality.p720);
put(18, VideoQuality.p360);
put(17, VideoQuality.p144);
put(6, VideoQuality.p270);
put(5, VideoQuality.p240);
}
};
public static String extractId(URL url) {
{
Pattern u = Pattern.compile("youtube.com/watch?.*v=([^&]*)");
Matcher um = u.matcher(url.toString());
if (um.find()) {
return um.group(1);
}
}
{
Pattern u = Pattern.compile("youtube.com/v/([^&]*)");
Matcher um = u.matcher(url.toString());
if (um.find()) {
return um.group(1);
}
}
return null;
}
/**
* allows to download age restricted videos
*
* @param info
* @param stop
* @param notify
* @throws Exception
*/
void extractEmbedded(final VideoInfo info, final AtomicBoolean stop, final Runnable notify) throws Exception {
String id = extractId(source);
if (id == null) {
throw new RuntimeException("unknown url");
}
info.setTitle(String.format("http://www.youtube.com/watch?v=%s", id));
String get = String
.format("http://www.youtube.com/get_video_info?video_id=%s&el=embedded&ps=default&eurl=", id);
URL url = new URL(get);
String qs = WGet.getHtml(url, new WGet.HtmlLoader() {
@Override
public void notifyRetry(int delay, Throwable e) {
info.setDelay(delay, e);
notify.run();
}
@Override
public void notifyDownloading() {
info.setState(States.DOWNLOADING);
notify.run();
}
@Override
public void notifyMoved() {
info.setState(States.RETRYING);
notify.run();
}
}, stop);
if (qs == null || qs.trim().length() == 0) {
qs = WGet.getHtml(url);
////below is sample code for simple HTTP GET with httpclient v4
////if used then apache commons-logging.jar is also required
// CloseableHttpClient httpclient = HttpClients.createDefault();
// try {
// HttpGet httpget = new HttpGet(get);
//
// System.out.println("Executing request " + httpget.getRequestLine());
//
// // Create a custom response handler
// ResponseHandler<String> responseHandler = new ResponseHandler<String>() {
//
// public String handleResponse(
// final HttpResponse response) throws ClientProtocolException, IOException {
// int status = response.getStatusLine().getStatusCode();
// if (status >= 200 && status < 300) {
// HttpEntity entity = response.getEntity();
// return entity != null ? EntityUtils.toString(entity) : null;
// } else {
// throw new ClientProtocolException("Unexpected response status: " + status);
// }
// }
//
// };
// String responseBody = httpclient.execute(httpget, responseHandler);
// qs = responseBody;
// } finally {
// httpclient.close();
// }
}
Map<String, String> map = getQueryMap(qs);
if (map.get("status").equals("fail")) {
String r = URLDecoder.decode(map.get("reason"), "UTF-8");
if (map.get("errorcode").equals("150")) {
throw new EmbeddingDisabled("error code 150");
}
if (map.get("errorcode").equals("100")) {
throw new VideoDeleted("error code 100");
}
throw new DownloadError(r);
// throw new PrivateVideoException(r);
}
info.setTitle(URLDecoder.decode(map.get("title"), "UTF-8"));
// String fmt_list = URLDecoder.decode(map.get("fmt_list"), "UTF-8");
// String[] fmts = fmt_list.split(",");
String url_encoded_fmt_stream_map = URLDecoder.decode(map.get("url_encoded_fmt_stream_map"), "UTF-8");
extractUrlEncodedVideos(url_encoded_fmt_stream_map);
// 'iurlmaxresæ or 'iurlsd' or 'thumbnail_url'
String icon = map.get("thumbnail_url");
icon = URLDecoder.decode(icon, "UTF-8");
info.setIcon(new URL(icon));
}
void extractIcon(VideoInfo info, String html) {
try {
Pattern title = Pattern.compile("itemprop=\"thumbnailUrl\" href=\"(.*)\"");
Matcher titleMatch = title.matcher(html);
if (titleMatch.find()) {
String sline = titleMatch.group(1);
sline = StringEscapeUtils.unescapeHtml4(sline);
info.setIcon(new URL(sline));
}
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static Map<String, String> getQueryMap(String qs) {
try {
qs = qs.trim();
List<NameValuePair> list;
list = URLEncodedUtils.parse(new URI(null, null, null, -1, null, qs, null), "UTF-8");
HashMap<String, String> map = new HashMap<String, String>();
for (NameValuePair p : list) {
map.put(p.getName(), p.getValue());
}
return map;
} catch (URISyntaxException e) {
throw new RuntimeException(qs, e);
}
}
void extractHtmlInfo(VideoInfo info, String html, AtomicBoolean stop, Runnable notify) throws Exception {
{
Pattern age = Pattern.compile("(verify_age)");
Matcher ageMatch = age.matcher(html);
if (ageMatch.find()) {
throw new AgeException();
}
}
{
Pattern age = Pattern.compile("(unavailable-player)");
Matcher ageMatch = age.matcher(html);
if (ageMatch.find()) {
throw new VideoUnavailablePlayer();
}
}
{
Pattern urlencod = Pattern.compile("\"url_encoded_fmt_stream_map\": \"([^\"]*)\"");
Matcher urlencodMatch = urlencod.matcher(html);
if (urlencodMatch.find()) {
String url_encoded_fmt_stream_map;
url_encoded_fmt_stream_map = urlencodMatch.group(1);
// normal embedded video, unable to grab age restricted videos
Pattern encod = Pattern.compile("url=(.*)");
Matcher encodMatch = encod.matcher(url_encoded_fmt_stream_map);
if (encodMatch.find()) {
String sline = encodMatch.group(1);
extractUrlEncodedVideos(sline);
}
// stream video
Pattern encodStream = Pattern.compile("stream=(.*)");
Matcher encodStreamMatch = encodStream.matcher(url_encoded_fmt_stream_map);
if (encodStreamMatch.find()) {
String sline = encodStreamMatch.group(1);
String[] urlStrings = sline.split("stream=");
for (String urlString : urlStrings) {
urlString = StringEscapeUtils.unescapeJava(urlString);
Pattern link = Pattern.compile("(sparams.*)&itag=(\\d+)&.*&conn=rtmpe(.*),");
Matcher linkMatch = link.matcher(urlString);
if (linkMatch.find()) {
String sparams = linkMatch.group(1);
String itag = linkMatch.group(2);
String url = linkMatch.group(3);
url = "http" + url + "?" + sparams;
url = URLDecoder.decode(url, "UTF-8");
addVideo(itag, url);
}
}
}
}
}
{
Pattern title = Pattern.compile("<meta name=\"title\" content=(.*)");
Matcher titleMatch = title.matcher(html);
if (titleMatch.find()) {
String sline = titleMatch.group(1);
String name = sline.replaceFirst("<meta name=\"title\" content=", "").trim();
name = StringUtils.strip(name, "\">");
name = StringEscapeUtils.unescapeHtml4(name);
info.setTitle(name);
}
}
}
void extractUrlEncodedVideos(String sline) throws Exception {
String[] urlStrings = sline.split("url=");
for (String urlString : urlStrings) {
urlString = StringEscapeUtils.unescapeJava(urlString);
// universal request
{
String url = null;
{
Pattern link = Pattern.compile("([^&]*)&");
Matcher linkMatch = link.matcher(urlString);
if (linkMatch.find()) {
url = linkMatch.group(1);
url = URLDecoder.decode(url, "UTF-8");
}
}
String itag = null;
{
Pattern link = Pattern.compile("itag=(\\d+)");
Matcher linkMatch = link.matcher(urlString);
if (linkMatch.find()) {
itag = linkMatch.group(1);
}
}
String sig = null;
{
Pattern link = Pattern.compile("signature=([^&,]*)");
Matcher linkMatch = link.matcher(urlString);
if (linkMatch.find()) {
sig = linkMatch.group(1);
} else {
link = Pattern.compile("signature%3D([^&,%]*)");
linkMatch = link.matcher(urlString);
if (linkMatch.find()) {
sig = linkMatch.group(1);
}
}
}
if (url != null && itag != null && sig != null) {
try {
new URL(url);
if (sig != null) {
url += "&signature=" + sig;
}
if (itag != null) {
addVideo(itag, url);
continue;
}
} catch (MalformedURLException e) {
// ignore bad urls
}
}
}
}
}
@Override
public void extract(VideoInfo info, AtomicBoolean stop, Runnable notify) {
try {
downloadone(info, stop, notify);
getVideo(info, sNextVideoURL);
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
- 1. Youtube POST in Java laden
- 2. Lazy Laden Youtube-Video von Iframe API
- 3. Laden Sie NUR Audio von einem Youtube-Video herunter.
- 4. Embed Youtube Video ohne Youtube-Link
- 5. YouTube-Video in HTML5
- 6. So laden Sie Youtube Thumbnails in einer RecyclerView mit Youtube API
- 7. So senden Sie YouTube-Video-Metadaten über AJAX
- 8. Youtube Video Player in C#
- 9. So speichern Sie Video in einer Video-Webanwendung
- 10. Responsive Youtube Video - Collapsing
- 11. Laden Sie das erste Video von jedem Suchergebnis von Youtube mit youtube-dl herunter?
- 12. So laden Sie große Bilder in Java
- 13. Youtube-Video in iFrame einbetten
- 14. Verwenden Sie YouTube Video für Webgl Textur?
- 15. Video Kulturen Youtube beim Laden es StageWebView mit
- 16. android youtube: teilen Sie ein Youtube-Video zu meiner App?
- 17. YouTube-Video-Wiedergabe mit ExoPlayer
- 18. YouTube-Video in R-Abschrift
- 19. spielen youtube video in WebView
- 20. Youtube-Video in JavaFX abspielen
- 21. Wie validieren Sie YouTube Video-IDs?
- 22. Erhalten Sie Untertitel "cc" für Youtube-Video
- 23. Erstellen Sie einen zufälligen Youtube-Video-Player
- 24. erhalten YouTube-Video-ID von iframe Video
- 25. ios7 UIWebView Youtube Video
- 26. Download YouTube Video .NET
- 27. YouTube-API: Video-Datenschutzoption
- 28. Video.js Youtube Video
- 29. On Play: Machen Sie Youtube Video Vollbild
- 30. Vimeo oder Youtube Video in React Native
Können wir diese für kommerzielle Zwecke? Ich meine, gibt es eine Lizenz dafür. –
@Shabarinath Ich kann nur mit Sicherheit sagen, dass der von mir gepostete Code frei ist, so wie Sie möchten. Soweit vget und die Bibliotheken davon abhängen, bin ich nicht sicher, ob ich wahrscheinlich denken würde, dass sie frei sind, in einem kommerziellen Projekt verwendet zu werden, aber nicht kommerziell verkauft werden, wie z.B. Ich verkaufe Vget. Aber all das sind nur Spekulationen, ich schlage vor, Sie überprüfen ihre Lizenzen mindestens die von vget und wget. – melc
Fertig funktionierendes Beispiel Link funktioniert nicht – Confuse