从Java,Android上的Youtube下载video代码
我创build了从Youtube上下载video的代码,但是这个代码不适用于Wi-Fi连接,并且可以使用移动连接。 我哪里有错误?
import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.util.Enumeration; import java.util.Vector; import android.app.Activity; import android.app.ProgressDialog; import android.net.Uri; import android.os.AsyncTask; import android.os.Bundle; import android.util.Log; import android.widget.MediaController; import android.widget.VideoView; public class MyActivity extends Activity { private class ReceivingDataFromYoutube extends AsyncTask<String, Void, Void> { private ProgressDialog dialog = new ProgressDialog(MyActivity.this); private String result; protected void onPreExecute() { dialog.setMessage("Downloading..."); dialog.show(); } @Override protected Void doInBackground(String... arg0) { int begin, end; String tmpstr = null; try { URL url=new URL("http://www.youtube.com/watch?v=y12-1miZHLs&nomobile=1"); HttpURLConnection con = (HttpURLConnection) url.openConnection(); con.setRequestMethod("GET"); InputStream stream=con.getInputStream(); InputStreamReader reader=new InputStreamReader(stream); StringBuffer buffer=new StringBuffer(); char[] buf=new char[262144]; int chars_read; while ((chars_read = reader.read(buf, 0, 262144)) != -1) { buffer.append(buf, 0, chars_read); } tmpstr=buffer.toString(); begin = tmpstr.indexOf("url_encoded_fmt_stream_map="); end = tmpstr.indexOf("&", begin + 27); if (end == -1) { end = tmpstr.indexOf("\"", begin + 27); } tmpstr = UtilClass.URLDecode(tmpstr.substring(begin + 27, end)); } catch (MalformedURLException e) { throw new RuntimeException(); } catch (IOException e) { throw new RuntimeException(); } Vector url_encoded_fmt_stream_map = new Vector(); begin = 0; end = tmpstr.indexOf(","); while (end != -1) { url_encoded_fmt_stream_map.addElement(tmpstr.substring(begin, end)); begin = end + 1; end = tmpstr.indexOf(",", begin); } url_encoded_fmt_stream_map.addElement(tmpstr.substring(begin, tmpstr.length())); String result = ""; Enumeration url_encoded_fmt_stream_map_enum = url_encoded_fmt_stream_map.elements(); while (url_encoded_fmt_stream_map_enum.hasMoreElements()) { tmpstr = (String)url_encoded_fmt_stream_map_enum.nextElement(); begin = tmpstr.indexOf("itag="); if (begin != -1) { end = tmpstr.indexOf("&", begin + 5); if (end == -1) { end = tmpstr.length(); } int fmt = Integer.parseInt(tmpstr.substring(begin + 5, end)); if (fmt == 35) { begin = tmpstr.indexOf("url="); if (begin != -1) { end = tmpstr.indexOf("&", begin + 4); if (end == -1) { end = tmpstr.length(); } result = UtilClass.URLDecode(tmpstr.substring(begin + 4, end)); this.result=result; break; } } } } try { URL u = new URL(result); HttpURLConnection c = (HttpURLConnection) u.openConnection(); c.setRequestMethod("GET"); /* c.setRequestProperty("Youtubedl-no-compression", "True"); c.setRequestProperty("User-Agent", "YouTube");*/ c.setDoOutput(true); c.connect(); FileOutputStream f=new FileOutputStream(new File("/sdcard/3.flv")); InputStream in=c.getInputStream(); byte[] buffer=new byte[1024]; int sz = 0; while ( (sz = in.read(buffer)) > 0 ) { f.write(buffer,0, sz); } f.close(); } catch (MalformedURLException e) { new RuntimeException(); } catch (IOException e) { new RuntimeException(); } return null; } protected void onPostExecute(Void unused) { dialog.dismiss(); } } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); new ReceivingDataFromYoutube().execute(); } }
3个步骤:
-
检查YouTube的代码(HTML),你会得到这样的链接(http%253A%252F%252Fo-o.preferred.telemar-cnf1.v18.lscache6.c.youtube.com%252Fvideoplayback …) ;
-
解码的url(删除代码%2B,%25等),创build一个解码器的代码: http : //www.w3schools.com/tags/ref_urlencode.asp和使用函数Uri.decode(url)replace无效逃逸的八位字节;
-
使用代码下载stream:
URL u = null; InputStream is = null; try { u = new URL(url); is = u.openStream(); HttpURLConnection huc = (HttpURLConnection)u.openConnection(); //to know the size of video int size = huc.getContentLength(); if(huc != null) { String fileName = "FILE.mp4"; String storagePath = Environment.getExternalStorageDirectory().toString(); File f = new File(storagePath,fileName); FileOutputStream fos = new FileOutputStream(f); byte[] buffer = new byte[1024]; int len1 = 0; if(is != null) { while ((len1 = is.read(buffer)) > 0) { fos.write(buffer,0, len1); } } if(fos != null) { fos.close(); } } } catch (MalformedURLException mue) { mue.printStackTrace(); } catch (IOException ioe) { ioe.printStackTrace(); } finally { try { if(is != null) { is.close(); } } catch (IOException ioe) { // just going to ignore this one } }
这就是大部分你会在网上find的东西!
方法1 (推荐)
图书馆YouTubeExtractor
join你的gradle文件
allprojects { repositories { maven { url "https://jitpack.io" } } }
和依赖关系
compile 'com.github.Commit451.YouTubeExtractor:youtubeextractor:2.1.0'
添加这个小代码,你完成了。 在这里演示
public class MainActivity extends AppCompatActivity { private static final String YOUTUBE_ID = "ea4-5mrpGfE"; private final YouTubeExtractor mExtractor = YouTubeExtractor.create(); private Callback<YouTubeExtractionResult> mExtractionCallback = new Callback<YouTubeExtractionResult>() { @Override public void onResponse(Call<YouTubeExtractionResult> call, Response<YouTubeExtractionResult> response) { bindVideoResult(response.body()); } @Override public void onFailure(Call<YouTubeExtractionResult> call, Throwable t) { onError(t); } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // For android youtube extractor library com.github.Commit451.YouTubeExtractor:youtubeextractor:2.1.0' mExtractor.extract(YOUTUBE_ID).enqueue(mExtractionCallback); } private void onError(Throwable t) { t.printStackTrace(); Toast.makeText(MainActivity.this, "It failed to extract. So sad", Toast.LENGTH_SHORT).show(); } private void bindVideoResult(YouTubeExtractionResult result) { // Here you can get download url link Log.d("OnSuccess", "Got a result with the best url: " + result.getBestAvailableQualityVideoUri()); Toast.makeText(this, "result : " + result.getSd360VideoUri(), Toast.LENGTH_SHORT).show(); } }
你可以在bindVideoResult()方法中获得下载链接。
方法2
使用这个库android-youtubeExtractor
添加到gradle文件中
repositories { maven { url "https://jitpack.io" } } compile 'com.github.HaarigerHarald:android-youtubeExtractor:master-SNAPSHOT'
这里是获取下载url的代码。
String youtubeLink = "http://youtube.com/watch?v=xxxx"; YouTubeUriExtractor ytEx = new YouTubeUriExtractor(this) { @Override public void onUrisAvailable(String videoId, String videoTitle, SparseArray<YtFile> ytFiles) { if (ytFiles != null) { int itag = 22; // Here you can get download url String downloadUrl = ytFiles.get(itag).getUrl(); } } }; ytEx.execute(youtubeLink);