2011-01-15 8 views
14

तक पहुंच प्राप्त करें मैं एक यूट्यूब वीडियो एक्सेस करना चाहता हूं और अपने मीडिया प्लेयर का उपयोग करके खेलना चाहता हूं। मैं यूट्यूब डेटा एपीआई का उपयोग कर वीडियो गुण (शीर्षक, यूआरएल आदि ..) प्राप्त करने में सक्षम हूं। क्या मैं वीडियो की स्ट्रीम तक पहुंच प्राप्त कर सकता हूं और इसे चलाने के लिए अपने स्वयं के मीडिया प्लेयर (एंड्रॉइड मीडिया प्लेयर की तरह) का उपयोग कर सकता हूं। मैं इन सभी को जावा में आजमा रहा हूं।यूट्यूब डेटा एपीआई: मीडिया स्ट्रीम और प्ले (जावा)

अग्रिम धन्यवाद .. :)

+0

जावास्क्रिप्ट निशांत – sharath

+1

@Nishant इसके लायक है कि छोटे नगण्य सुधार के लिए टिप्पणी है? – Petruza

उत्तर

8

आप नहीं कर सकते। एपीआई क्या संभाल सकता है इस पर आगे पढ़ने के लिए यहां देखें: YoutubeAPI
यदि आप उस पर इनपुटस्ट्रीम प्राप्त कर सकते हैं, तो Google को विज्ञापन के लिए कोई पैसा नहीं मिलेगा।

लेकिन आप एपीआई से प्राप्त वीडियो-यूआरएल के पेज को पार्स कर सकते हैं और फ्लैश टैग के अंदर असली वीडियो-लिंक ढूंढ सकते हैं।

11
/** 
* This work is licensed under a Creative Commons Attribution 3.0 Unported 
* License (http://creativecommons.org/licenses/by/3.0/). This work is placed 
* into the public domain by the author. 
*/ 
import java.io.BufferedReader; 
import java.io.File; 
import java.io.FileOutputStream; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.InputStreamReader; 
import java.io.Reader; 
import java.io.StringWriter; 
import java.io.UnsupportedEncodingException; 
import java.io.Writer; 
import java.net.URI; 
import java.net.URISyntaxException; 
import java.text.DecimalFormat; 
import java.util.ArrayList; 
import java.util.List; 
import java.util.Scanner; 
import java.util.logging.Formatter; 
import java.util.logging.Handler; 
import java.util.logging.Level; 
import java.util.logging.LogRecord; 
import java.util.logging.Logger; 
import java.util.regex.Pattern; 

import org.apache.http.HttpEntity; 
import org.apache.http.HttpResponse; 
import org.apache.http.NameValuePair; 
import org.apache.http.client.CookieStore; 
import org.apache.http.client.HttpClient; 
import org.apache.http.client.methods.HttpGet; 
import org.apache.http.client.protocol.ClientContext; 
import org.apache.http.client.utils.URIUtils; 
import org.apache.http.client.utils.URLEncodedUtils; 
import org.apache.http.impl.client.BasicCookieStore; 
import org.apache.http.impl.client.DefaultHttpClient; 
import org.apache.http.message.BasicNameValuePair; 
import org.apache.http.protocol.BasicHttpContext; 
import org.apache.http.protocol.HttpContext; 

/** 
* Locally download a YouTube.com video. 
*/ 
public class JavaYoutubeDownloader extends Formatter { 

private static final String scheme = "http"; 
private static final String host = "www.youtube.com"; 
private static final String YOUTUBE_WATCH_URL_PREFIX = scheme + "://" + host + "/watch?v="; 
private static final String ERROR_MISSING_VIDEO_ID = "Missing video id. Extract from " + YOUTUBE_WATCH_URL_PREFIX + "VIDEO_ID"; 
private static final String DEFAULT_USER_AGENT = "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.13) Gecko/20101203 Firefox/3.6.13"; 
private static final String DEFAULT_ENCODING = "UTF-8"; 
private static final String newline = System.getProperty("line.separator"); 
private static final Logger log = Logger.getLogger(JavaYoutubeDownloader.class.getCanonicalName()); 
private static final Logger rootlog = Logger.getLogger(""); 
private static final Pattern commaPattern = Pattern.compile(","); 
private static final Pattern pipePattern = Pattern.compile("\\|"); 
private static final char[] ILLEGAL_FILENAME_CHARACTERS = { '/', '\n', '\r', '\t', '\0', '\f', '`', '?', '*', '\\', '<', '>', '|', '\"', ':' }; 
private static final int BUFFER_SIZE = 2048; 
private static final DecimalFormat commaFormatNoPrecision = new DecimalFormat("###,###"); 
private static final double ONE_HUNDRED = 100; 
private static final double KB = 1024; 

private void usage(String error) { 
    if (error != null) { 
    System.err.println("Error: " + error); 
    } 
    System.err.println("usage: JavaYoutubeDownload VIDEO_ID"); 
    System.err.println(); 
    System.err.println("Options:"); 
    System.err.println("\t[-dir DESTINATION_DIR] - Specify output directory."); 
    System.err.println("\t[-format FORMAT] - Format number" + newline + "\t\tSee http://en.wikipedia.org/wiki/YouTube#Quality_and_codecs"); 
    System.err.println("\t[-ua USER_AGENT] - Emulate a browser user agent."); 
    System.err.println("\t[-enc ENCODING] - Default character encoding."); 
    System.err.println("\t[-verbose] - Verbose logging for downloader component."); 
    System.err.println("\t[-verboseall] - Verbose logging for all components (e.g. HttpClient)."); 
    System.exit(-1); 
} 

public static void main(String[] args) { 
    try { 
    new JavaYoutubeDownloader().run(args); 
    } catch (Throwable t) { 
    t.printStackTrace(); 
    } 
} 

private void run(String[] args) throws Throwable { 
    setupLogging(Level.WARNING, Level.WARNING); 

    String videoId = null; 
    String outdir = "."; 
    int format = 18; 
    String encoding = DEFAULT_ENCODING; 
    String userAgent = DEFAULT_USER_AGENT; 

    for (int i = 0; i < args.length; i++) { 
    String arg = args[i]; 

    // Options start with either -, -- 
    // Do not accept Windows-style args that start with/because of abs 
    // paths on linux for file names. 
    if (arg.charAt(0) == '-') { 

    // For easier processing, convert any double dashes to 
    // single dashes 
    if (arg.length() > 1 && arg.charAt(1) == '-') { 
    arg = arg.substring(1); 
    } 

    String larg = arg.toLowerCase(); 

    // Process the option 
    if (larg.equals("-help") || larg.equals("-?") || larg.equals("-usage") || larg.equals("-h")) { 
    usage(null); 
    } else if (larg.equals("-verbose")) { 
    setupLogging(Level.ALL, Level.WARNING); 
    } else if (larg.equals("-verboseall")) { 
    setupLogging(Level.ALL, Level.ALL); 
    } else if (larg.equals("-dir")) { 
    outdir = args[++i]; 
    } else if (larg.equals("-format")) { 
    format = Integer.parseInt(args[++i]); 
    } else if (larg.equals("-ua")) { 
    userAgent = args[++i]; 
    } else if (larg.equals("-enc")) { 
    encoding = args[++i]; 
    } else { 
    usage("Unknown command line option " + args[i]); 
    } 
    } else { 
    // Non-option (i.e. does not start with -, -- 

    videoId = arg; 

    // Break if only the first non-option should be used. 
    break; 
    } 
    } 

    if (videoId == null) { 
    usage(ERROR_MISSING_VIDEO_ID); 
    } 

    log.fine("Starting"); 

    if (videoId.startsWith(YOUTUBE_WATCH_URL_PREFIX)) { 
    videoId = videoId.substring(YOUTUBE_WATCH_URL_PREFIX.length()); 
    } 
    int a = videoId.indexOf('&'); 
    if (a != -1) { 
    videoId = videoId.substring(0, a); 
    } 

    File outputDir = new File(outdir); 
    String extension = getExtension(format); 

    play(videoId, format, encoding, userAgent, outputDir, extension); 

    log.fine("Finished"); 
} 

private static String getExtension(int format) { 
    switch (format) { 
    case 18: 
    return "mp4"; 
    default: 
    throw new Error("Unsupported format " + format); 
    } 
} 

private static void play(String videoId, int format, String encoding, String userAgent, File outputdir, String extension) throws Throwable { 
    log.fine("Retrieving " + videoId); 
    List<NameValuePair> qparams = new ArrayList<NameValuePair>(); 
    qparams.add(new BasicNameValuePair("video_id", videoId)); 
    qparams.add(new BasicNameValuePair("fmt", "" + format)); 
    URI uri = getUri("get_video_info", qparams); 

    CookieStore cookieStore = new BasicCookieStore(); 
    HttpContext localContext = new BasicHttpContext(); 
    localContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore); 

    HttpClient httpclient = new DefaultHttpClient(); 
    HttpGet httpget = new HttpGet(uri); 
    if (userAgent != null && userAgent.length() > 0) { 
    httpget.setHeader("User-Agent", userAgent); 
    } 

    log.finer("Executing " + uri); 
    HttpResponse response = httpclient.execute(httpget, localContext); 
    HttpEntity entity = response.getEntity(); 
    if (entity != null && response.getStatusLine().getStatusCode() == 200) { 
    InputStream instream = entity.getContent(); 
    String videoInfo = getStringFromInputStream(encoding, instream); 
    if (videoInfo != null && videoInfo.length() > 0) { 
    List<NameValuePair> infoMap = new ArrayList<NameValuePair>(); 
    URLEncodedUtils.parse(infoMap, new Scanner(videoInfo), encoding); 
    String downloadUrl = null; 
    String filename = videoId; 

    for (NameValuePair pair : infoMap) { 
    String key = pair.getName(); 
    String val = pair.getValue(); 
    log.finest(key + "=" + val); 
    if (key.equals("title")) { 
     filename = val; 
    } else if (key.equals("fmt_url_map")) { 
     String[] formats = commaPattern.split(val); 
     boolean found = false; 
     for (String fmt : formats) { 
     String[] fmtPieces = pipePattern.split(fmt); 
     if (fmtPieces.length == 2) { 
     int pieceFormat = Integer.parseInt(fmtPieces[0]); 
     log.fine("Available format=" + pieceFormat); 
     if (pieceFormat == format) { 
     // found what we want 
     downloadUrl = fmtPieces[1]; 
     found = true; 
     break; 
     } 
     } 
     } 
     if (!found) { 
     log.warning("Could not find video matching specified format, however some formats of the video do exist (use -verbose)."); 
     } 
    } 
    } 

    filename = cleanFilename(filename); 
    if (filename.length() == 0) { 
    filename = videoId; 
    } else { 
    filename += "_" + videoId; 
    } 
    filename += "." + extension; 
    File outputfile = new File(outputdir, filename); 

    if (downloadUrl != null) { 
    downloadWithHttpClient(userAgent, downloadUrl, outputfile); 
    } else { 
    log.severe("Could not find video"); 
    } 
    } else { 
    log.severe("Did not receive content from youtube"); 
    } 
    } else { 
    log.severe("Could not contact youtube: " + response.getStatusLine()); 
    } 
} 

private static void downloadWithHttpClient(String userAgent, String downloadUrl, File outputfile) throws Throwable { 
    HttpGet httpget2 = new HttpGet(downloadUrl); 
    if (userAgent != null && userAgent.length() > 0) { 
    httpget2.setHeader("User-Agent", userAgent); 
    } 

    log.finer("Executing " + httpget2.getURI()); 
    HttpClient httpclient2 = new DefaultHttpClient(); 
    HttpResponse response2 = httpclient2.execute(httpget2); 
    HttpEntity entity2 = response2.getEntity(); 
    if (entity2 != null && response2.getStatusLine().getStatusCode() == 200) { 
    double length = entity2.getContentLength(); 
    if (length <= 0) { 
    // Unexpected, but do not divide by zero 
    length = 1; 
    } 
    InputStream instream2 = entity2.getContent(); 
    System.out.println("Writing " + commaFormatNoPrecision.format(length) + " bytes to " + outputfile); 
    if (outputfile.exists()) { 
    outputfile.delete(); 
    } 
    FileOutputStream outstream = new FileOutputStream(outputfile); 
    try { 
    byte[] buffer = new byte[BUFFER_SIZE]; 
    double total = 0; 
    int count = -1; 
    int progress = 10; 
    long start = System.currentTimeMillis(); 
    while ((count = instream2.read(buffer)) != -1) { 
    total += count; 
    int p = (int) ((total/length) * ONE_HUNDRED); 
    if (p >= progress) { 
     long now = System.currentTimeMillis(); 
     double s = (now - start)/1000; 
     int kbpers = (int) ((total/KB)/s); 
     System.out.println(progress + "% (" + kbpers + "KB/s)"); 
     progress += 10; 
    } 
    outstream.write(buffer, 0, count); 
    } 
    outstream.flush(); 
    } finally { 
    outstream.close(); 
    } 
    System.out.println("Done"); 
    } 
} 

private static String cleanFilename(String filename) { 
    for (char c : ILLEGAL_FILENAME_CHARACTERS) { 
    filename = filename.replace(c, '_'); 
    } 
    return filename; 
} 

private static URI getUri(String path, List<NameValuePair> qparams) throws URISyntaxException { 
    URI uri = URIUtils.createURI(scheme, host, -1, "/" + path, URLEncodedUtils.format(qparams, DEFAULT_ENCODING), null); 
    return uri; 
} 

private void setupLogging(Level myLevel, Level globalLevel) { 
    changeFormatter(this); 
    explicitlySetAllLogging(myLevel, globalLevel); 
} 

@Override 
public String format(LogRecord arg0) { 
    return arg0.getMessage() + newline; 
} 

private static void changeFormatter(Formatter formatter) { 
    Handler[] handlers = rootlog.getHandlers(); 
    for (Handler handler : handlers) { 
    handler.setFormatter(formatter); 
    } 
} 

private static void explicitlySetAllLogging(Level myLevel, Level globalLevel) { 
    rootlog.setLevel(Level.ALL); 
    for (Handler handler : rootlog.getHandlers()) { 
    handler.setLevel(Level.ALL); 
    } 
    log.setLevel(myLevel); 
    rootlog.setLevel(globalLevel); 
} 

private static String getStringFromInputStream(String encoding, InputStream instream) throws UnsupportedEncodingException, IOException { 
    Writer writer = new StringWriter(); 

    char[] buffer = new char[1024]; 
    try { 
    Reader reader = new BufferedReader(new InputStreamReader(instream, encoding)); 
    int n; 
    while ((n = reader.read(buffer)) != -1) { 
    writer.write(buffer, 0, n); 
    } 
    } finally { 
    instream.close(); 
    } 
    String result = writer.toString(); 
    return result; 
} 
} 

/** 
* <pre> 
* Exploded results from get_video_info: 
* 
* fexp=909302 
* allow_embed=1 
* fmt_stream_map=35|http://v9.lscache8.c.youtube.com/videoplayback?ip=174.0.0.0&sparams=id%2Cexpire%2Cip%2Cipbits%2Citag%2Calgorithm%2Cburst%2Cfactor&fexp=909302&algorithm=throttle-factor&itag=35&ipbits=8&burst=40&sver=3&expire=1294549200&key=yt1&signature=9E0A8E67154145BCADEBCF844CC155282548288F.2BBD0B2E125E3E533D07866C7AE91B38DD625D30&factor=1.25&id=4ba2193f7c9127d2||tc.v9.cache8.c.youtube.com,34|http://v6.lscache3.c.youtube.com/videoplayback?ip=174.0.0.0&sparams=id%2Cexpire%2Cip%2Cipbits%2Citag%2Calgorithm%2Cburst%2Cfactor&fexp=909302&algorithm=throttle-factor&itag=34&ipbits=8&burst=40&sver=3&expire=1294549200&key=yt1&signature=6726793A7B041E6456B52C0972596D0D58974141.42B5A0573F62B85AEA7979E5EE1ADDD47EB9E909&factor=1.25&id=4ba2193f7c9127d2||tc.v6.cache3.c.youtube.com,18|http://v12.lscache7.c.youtube.com/videoplayback?ip=174.0.0.0&sparams=id%2Cexpire%2Cip%2Cipbits%2Citag%2Calgorithm%2Cburst%2Cfactor&fexp=909302&algorithm=throttle-factor&itag=18&ipbits=8&burst=40&sver=3&expire=1294549200&key=yt1&signature=AE58398D4CC4D760C682D2A5B670B4047777FFF0.952E4FC4554E786FD937E7A89140E1F79B6DD8B7&factor=1.25&id=4ba2193f7c9127d2||tc.v12.cache7.c.youtube.com,5|http://v1.lscache7.c.youtube.com/videoplayback?ip=174.0.0.0&sparams=id%2Cexpire%2Cip%2Cipbits%2Citag%2Calgorithm%2Cburst%2Cfactor&fexp=909302&algorithm=throttle-factor&itag=5&ipbits=8&burst=40&sver=3&expire=1294549200&key=yt1&signature=43434DCB6CFC463FF4522D9EE7CD019FE47237B1.C60A9522E361130938663AF2DAD83A5C2821AF5C&factor=1.25&id=4ba2193f7c9127d2||tc.v1.cache7.c.youtube.com 
* fmt_url_map=35|http://v9.lscache8.c.youtube.com/videoplayback?ip=174.0.0.0&sparams=id%2Cexpire%2Cip%2Cipbits%2Citag%2Calgorithm%2Cburst%2Cfactor&fexp=909302&algorithm=throttle-factor&itag=35&ipbits=8&burst=40&sver=3&expire=1294549200&key=yt1&signature=9E0A8E67154145BCADEBCF844CC155282548288F.2BBD0B2E125E3E533D07866C7AE91B38DD625D30&factor=1.25&id=4ba2193f7c9127d2,34|http://v6.lscache3.c.youtube.com/videoplayback?ip=174.0.0.0&sparams=id%2Cexpire%2Cip%2Cipbits%2Citag%2Calgorithm%2Cburst%2Cfactor&fexp=909302&algorithm=throttle-factor&itag=34&ipbits=8&burst=40&sver=3&expire=1294549200&key=yt1&signature=6726793A7B041E6456B52C0972596D0D58974141.42B5A0573F62B85AEA7979E5EE1ADDD47EB9E909&factor=1.25&id=4ba2193f7c9127d2,18|http://v12.lscache7.c.youtube.com/videoplayback?ip=174.0.0.0&sparams=id%2Cexpire%2Cip%2Cipbits%2Citag%2Calgorithm%2Cburst%2Cfactor&fexp=909302&algorithm=throttle-factor&itag=18&ipbits=8&burst=40&sver=3&expire=1294549200&key=yt1&signature=AE58398D4CC4D760C682D2A5B670B4047777FFF0.952E4FC4554E786FD937E7A89140E1F79B6DD8B7&factor=1.25&id=4ba2193f7c9127d2,5|http://v1.lscache7.c.youtube.com/videoplayback?ip=174.0.0.0&sparams=id%2Cexpire%2Cip%2Cipbits%2Citag%2Calgorithm%2Cburst%2Cfactor&fexp=909302&algorithm=throttle-factor&itag=5&ipbits=8&burst=40&sver=3&expire=1294549200&key=yt1&signature=43434DCB6CFC463FF4522D9EE7CD019FE47237B1.C60A9522E361130938663AF2DAD83A5C2821AF5C&factor=1.25&id=4ba2193f7c9127d2 
* allow_ratings=1 
* keywords=Stefan Molyneux,Luke Bessey,anarchy,stateless society,giant stone cow,the story of our unenslavement,market anarchy,voluntaryism,anarcho capitalism 
* track_embed=0 
* fmt_list=35/854x480/9/0/115,34/640x360/9/0/115,18/640x360/9/0/115,5/320x240/7/0/0 
* author=lukebessey 
* muted=0 
* length_seconds=390 
* plid=AASZXXGQtTEDKwAw 
* ftoken=null 
* status=ok 
* watermark=http://s.ytimg.com/yt/swf/logo-vfl_bP6ud.swf,http://s.ytimg.com/yt/swf/hdlogo-vfloR6wva.swf 
* timestamp=1294526523 
* has_cc=False 
* fmt_map=35/854x480/9/0/115,34/640x360/9/0/115,18/640x360/9/0/115,5/320x240/7/0/0 
* leanback_module=http://s.ytimg.com/yt/swfbin/leanback_module-vflJYyeZN.swf 
* hl=en_US 
* endscreen_module=http://s.ytimg.com/yt/swfbin/endscreen-vflk19iTq.swf 
* vq=auto 
* avg_rating=5.0 
* video_id=S6IZP3yRJ9I 
* token=vjVQa1PpcFNhI3jvw6hfEHivcKK-XY5gb-iszDMrooA= 
* thumbnail_url=http://i4.ytimg.com/vi/S6IZP3yRJ9I/default.jpg 
* title=The Story of Our Unenslavement - Animated 
* </pre> 
*/ 
संबंधित मुद्दे