Я пытаюсь выяснить, как загрузить видео с youtube в локальную файловую систему. Я пробовал несколько пакетов, таких как vGet, но не могу заставить их работать. Буду признателен за любую оказанную помощь.Как скачать видео Youtube в java
ответ
Я попытался vget, https://github.com/axet/vget (переехал в https://gitlab.com/axet/vget) и она отлично работает. Вы можете использовать maven для настройки или загрузки зависимостей вручную от файлов pom. Зависимости
Wget (https://github.com/axet/wget)
Обще-IO-2.4.jar
Викисклада lang3-3.1.jar
httpcore-4.3.jar
httpclient-4.3.jar
XStream-1.4.2.jar
скомпилирован с JDK6
побежал прямой скачать образец как,
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);
}
}
}
Заканчивать готовый рабочий пример, источники включены в баночка
Почтовый индекс - 1,89KB
https://www.wetransfer.com/downloads/465f7ef8c6a76f79e4cbd7c9f38a608c20131005141332/41c09a86ed8eaa6e61f59282eabda2a120131005141332/4ac689
UPDATE # - NPE проблема при загрузке, как указано в комментариях
tldr; Кажется, что есть несколько проблем с com.github.axet.vget.vhs.YouTubeParser
, поэтому добавлен неинтрузивный код, чтобы исправить его и заставить пример работать так, как он привык. Так что просто замените оригинальный класс YoutubeParser
тем, который был опубликован здесь в конце.
Также найдите еще один готовый рабочий пример с банкой и всеми необходимыми библиотеками, источники включены в банку (это будет автоматически удалено через некоторое время (будет удалено 13 сентября 2014 года) - включены URL-адреса youtube в коде случайны)
почтовый файл - 1,69MB (wetransfer.com отображает 1.7MB)
A. ВОПРОСЫ
В com.github.axet.vget.vhs.YouTubeParser ln229 переменная
qs
большую часть времени он не содержит полученную строку запроса в HTTP GET выполняется сWGet
. Это приводит к тому, чтоnpe
будет брошен позже при попытке проанализировать строку запроса.Если проблема 1 решена, то переменная
sig
не найден в URLs вернулся изget_video_info
, поэтому разбор сPattern.compile("sig=([^&,]*)")
не возвращает никаких значений. Это приводит к непрерывным повторным попыткам без загрузки видео.
B. РЕШЕНИЯ(это временные участки, как оригинальный формат ответа и причины WGET плохое поведение не известны)
- Вызов
WGet
еще раз, если строка запроса пуста, безWGet.HtmlLoader
, похоже, выполняет эту работу. Также предусмотрен подход вызова простого HTTP GET с использованием apache httpclient v4, в этом случае есть еще одна зависимость от apache commons-logging.jar.
добавлены в ln248
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.После глядя на ответ, кажется, подпись в определенном месте, так что усиливало разборе немного. Таким образом, если выполнение шаблона Pattern.compile("sig=([^&,]*)")
не возвращает ничего, то также пытается с Pattern.compile("signature%3D([^&,%]*)")
. Это изменение имело место в методе 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);
}
}
}
Модифицированный com.github.axet.vget.vhs.YouTubeParser
файл следующим образом,
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 на java?
- 2. Скачать YouTube видео .NET
- 3. Youtube видео скачать URL
- 4. скачать видео с youtube
- 5. PHP YouTube видео скачать
- 6. Как скачать видео YouTube в универсальном приложении?
- 7. Скачать видео Youtube с cordova
- 8. Скачать rtmpe видео с youtube?
- 9. Java, как скачать видео с youtube, vget alternative?
- 10. как скачать видео FLV видео напрямую с YouTube
- 11. youtube-dl скачать видео с formatid
- 12. Как скачать youtube 1080p программой
- 13. Android Youtube Скачать mp3
- 14. youtube-dl скачать место
- 15. скачать youtube видео в формате mp3 в iOS Swift
- 16. Как скачать видео с youtube и сохранить (цель c)?
- 17. youtube встроенный плеер скачать видео как атрибуты кнопки mp4
- 18. Как скачать видео с YouTube с помощью рубина?
- 19. Python-Скачать видео с youtube и конвертировать его в mp3
- 20. python- скачать mp3 из YouTube
- 21. [Android] Загрузка видео Youtube
- 22. Как захватить Youtube Скачать ссылки Расшифровка шифров, используемых Youtube?
- 23. YouTube-dl, чтобы скачать и назвать видео от Reddit
- 24. Скачать видео файл YouTube непосредственно к компьютеру пользователя через браузер
- 25. Как скачать видео с youtube, а также обрезать или вырезать загруженное видео в iphone sdk?
- 26. Скачать HTML с YouTube
- 27. Видео YouTube хотят скачать вместо загрузки через jQuery
- 28. Встраивание видео YouTube
- 29. видео скачать/поток с помощью Java-сервлет
- 30. Как скачать флеш-видео с этого сайта?
Можем ли мы использовать это в коммерческих целях? Я имею в виду, есть ли лицензия на это. –
@Shabarinath. Я могу только точно сказать, что код, отправленный мной, может быть использован любым способом, который вам нравится. Насколько vget и библиотеки это зависит от, я не уверен, что, вероятно, думаю, что они могут свободно использоваться в коммерческом проекте, но не продаются коммерчески, как, например, Я продаю vget. Но все это всего лишь предположения, я предлагаю вам проверить свои лицензии, по крайней мере, на версии vget и wget. – melc
Готовый рабочий пример ссылки не работает – Confuse