Xu Hướng 4/2024 # Java — Mã Để Tải Xuống Video Từ Youtube Trên Java, Android # Top 4 Yêu Thích

initTypeMap (); gọi trước

class Meta {

public String num;

public String type;

public String ext;

Meta(String num, String ext, String type) {

chúng tôi = num;

chúng tôi = ext;

chúng tôi = type;

}

}

class Video {

public String ext = "";

public String type = "";

public String url = "";

Video(String ext, String type, String url) {

chúng tôi = ext;

chúng tôi = type;

chúng tôi = url;

}

}

throws IOException {

if (ytUrl == null) {

return null;

}

int andIdx = ytUrl.indexOf('&');

ytUrl = ytUrl.substring(0, andIdx);

}

/* String userAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:8.0.1)";*/

/* HttpClient client = new DefaultHttpClient();

client.getParams().setParameter(CoreProtocolPNames.USER_AGENT,

userAgent);

HttpGet request = new HttpGet(ytUrl);

HttpResponse response = client.execute(request);*/

String html = "";

HttpsURLConnection c = (HttpsURLConnection) new URL(ytUrl).openConnection();

c.setRequestMethod("GET");

c.setDoOutput(true);

c.connect();

InputStream in = c.getInputStream();

BufferedReader reader = new BufferedReader(new InputStreamReader(in));

StringBuilder str = new StringBuilder();

String line = null;

while ((line = reader.readLine()) != null) {

str.append(line.replace("\u0026", "&"));

}

in.close();

html = str.toString();

if (html.contains("verify-age-thumb")) {

Log.e("Downloader", "YouTube is asking for age verification. We can't handle that sorry.");

return null;

}

if (html.contains("das_captcha")) {

Log.e("Downloader", "Captcha found, please try with different IP address.");

return null;

}

Pattern p = Pattern.compile("stream_map":"(.*?)?"");

Matcher m = p.matcher(html);

while (m.find()) {

matches.add(m.group());

}

if (matches.size() != 1) {

Log.e("Downloader", "Found zero or too many stream maps.");

return null;

}

String urls[] = matches.get(0).split(",");

for (String ppUrl : urls) {

String url = URLDecoder.decode(ppUrl, "UTF-8");

Log.e("URL","URL : "+url);

Pattern p1 = Pattern.compile("itag=([0-9]+?)[&]");

Matcher m1 = p1.matcher(url);

String itag = null;

if (m1.find()) {

itag = m1.group(1);

}

Pattern p2 = Pattern.compile("signature=(.*?)[&]");

Matcher m2 = p2.matcher(url);

String sig = null;

if (m2.find()) {

sig = m2.group(1);

} else {

Pattern p23 = Pattern.compile("signature&s=(.*?)[&]");

Matcher m23 = p23.matcher(url);

if (m23.find()) {

sig = m23.group(1);

}

}

Pattern p3 = Pattern.compile("url=(.*?)[&]");

Matcher m3 = p3.matcher(ppUrl);

String um = null;

if (m3.find()) {

um = m3.group(1);

}

if (itag != null && sig != null && um != null) {

Log.e("foundArray","Adding Value");

foundArray.put(itag, URLDecoder.decode(um, "UTF-8") + "&"

+ "signature=" + sig);

}

}

Log.e("foundArray","Size : "+foundArray.size());

if (foundArray.size() == 0) {

Log.e("Downloader", "Couldn't find any URLs and corresponding signatures");

return null;

}

for (String format : typeMap.keySet()) {

Meta meta = typeMap.get(format);

if (foundArray.containsKey(format)) {

Video newVideo = new Video(meta.ext, meta.type,

foundArray.get(format));

videos.add(newVideo);

Log.d("Downloader", "YouTube Video streaming details: ext:" + newVideo.ext

+ ", type:" + chúng tôi + ", url:" + newVideo.url);

}

}

return videos;

}

ProgressDialog progressDialog;

@Override

protected void onPreExecute() {

super.onPreExecute();

progressDialog = ProgressDialog.show(webViewActivity.this, "",

"Connecting to YouTube...", true);

}

@Override

String url = params[0];

try {

/* Log.e("Downloader","Size of Video : "+videos.size());*/

if (videos != null && !videos.isEmpty()) {

for (Video video : videos)

{

Log.e("Downloader", "ext : " + video.ext);

ext = video.ext.toLowerCase();

fVideos.add(new Video(video.ext,video.type,video.url));

}

}

return fVideos;

}

} catch (Exception e) {

e.printStackTrace();

Log.e("Downloader", "Couldn't get YouTube streaming URL", e);

}

Log.e("Downloader", "Couldn't get stream URI for " + url);

return null;

}

@Override

super.onPostExecute(streamingUrl);

progressDialog.dismiss();

if (streamingUrl != null) {

if (!streamingUrl.isEmpty()) {

for (int i = 0; i < streamingUrl.size(); i++) {

Video fX = streamingUrl.get(i);

Log.e("Founded Video", "URL : " + fX.url);

Log.e("Founded Video", "TYPE : " + fX.type);

Log.e("Founded Video", "EXT : " + fX.ext);

}

}

}

}

}

public void initTypeMap()

{

typeMap.put("13", new Meta("13", "3GP", "Low Quality - 176x144"));

typeMap.put("17", new Meta("17", "3GP", "Medium Quality - 176x144"));

typeMap.put("36", new Meta("36", "3GP", "High Quality - 320x240"));

typeMap.put("5", new Meta("5", "FLV", "Low Quality - 400x226"));

typeMap.put("6", new Meta("6", "FLV", "Medium Quality - 640x360"));

typeMap.put("34", new Meta("34", "FLV", "Medium Quality - 640x360"));

typeMap.put("35", new Meta("35", "FLV", "High Quality - 854x480"));

typeMap.put("43", new Meta("43", "WEBM", "Low Quality - 640x360"));

typeMap.put("44", new Meta("44", "WEBM", "Medium Quality - 854x480"));

typeMap.put("45", new Meta("45", "WEBM", "High Quality - 1280x720"));

typeMap.put("18", new Meta("18", "MP4", "Medium Quality - 480x360"));

typeMap.put("22", new Meta("22", "MP4", "High Quality - 1280x720"));

typeMap.put("37", new Meta("37", "MP4", "High Quality - 1920x1080"));

typeMap.put("33", new Meta("38", "MP4", "High Quality - 4096x230"));

}

Chỉnh sửa 2:

Đôi khi Mã này không hoạt động đúng

Chính sách cùng nguồn gốc

https://en.wikipedia.org/wiki/Same-Origin_policy

https://en.wikipedia.org/wiki/Cross-Origin_resource_shaming

problem of Same-Origin policy. Essentially, you cannot download this file from chúng tôi because they are different domains. A workaround of this problem is [CORS][1].

Tham chiếu: https://superuser.com/questions/773719/how-do-all-of-these-save-video-from-youtube-service-work/773998#773998

url_encoded_fmt_stream_map

adaptive_fmts

Mỗi trong số này là một mảng được phân tách bằng dấu phẩy của cái mà tôi sẽ gọi là “đối tượng luồng”. Mỗi “đối tượng luồng” sẽ chứa các giá trị như thế này

url

itag

s

Mỗi URL sẽ được mã hóa, do đó bạn sẽ cần giải mã chúng. Bây giờ là phần khó khăn.

YouTube có ít nhất 3 cấp độ bảo mật cho video của họ

unsecured

s

RTMPE

Các video RTMPE thường được sử dụng trên các bộ phim có thời lượng đầy đủ chính thức và được bảo vệ với Loại xác minh SWF 2. Điều này đã có từ năm 2011 và vẫn chưa được thiết kế ngược.

Các loại video “s” là khó nhất thực sự có thể được tải xuống. Bạn sẽ thấy những thứ này trên các video của VEVO và những thứ tương tự. Họ bắt đầu bằng một chữ ký như

AA5D05FA7771AD4868BA4C977C3DEAAC620DE020E.0F421820F42978A1F8EAFCDAC4EF507DB5 Sau đó, chữ ký được xáo trộn với chức năng như thế này

function mo(a) {

a = a.split("");

a = lo.rw(a, 1);

a = lo.rw(a, 32);

a = lo.IC(a, 1);

a = lo.wS(a, 77);

a = lo.IC(a, 3);

a = lo.wS(a, 77);

a = lo.IC(a, 3);

a = lo.wS(a, 44);

return a.join("")

}

Chức năng này là năng động, nó thường thay đổi mỗi ngày. Để làm cho khó khăn hơn, chức năng được lưu trữ tại một URL như

http://s.ytimg.com/yts/jsbin/html5player-en_US-vflycBCEX.js

điều này giới thiệu vấn đề của chính sách Cùng nguồn gốc. Về cơ bản, bạn không thể tải xuống tệp này từ chúng tôi vì chúng là các miền khác nhau. Một cách giải quyết của vấn đề này là CORS. Với CORS, chúng tôi có ​​thể thêm tiêu đề này

Access-Control-Allow-Origin: http://www.youtube.com

và nó sẽ cho phép JavaScript tải xuống từ chúng tôi Tất nhiên họ không làm điều này. Một cách giải quyết cho cách giải quyết này là sử dụng proxy CORS. Đây là một proxy đáp ứng với tiêu đề sau cho tất cả các yêu cầu

Access-Control-Allow-Origin: *

Vì vậy, bây giờ bạn đã ủy quyền tệp JS của mình và sử dụng hàm để xáo trộn chữ ký, bạn có thể sử dụng nó trong chuỗi truy vấn để tải xuống video.