Youtube data API : Get access to media stream and play (JAVA)

后端 未结 3 794
耶瑟儿~
耶瑟儿~ 2020-12-31 06:16

I want to access a youtube video and play using my own media player. I am able to get the video properties (title, url etc..) using the youtube data API. Can I get access to

相关标签:
3条回答
  • 2020-12-31 06:21

    Now you can find it here now its available https://developers.google.com/youtube/android/player/sample-applications

    0 讨论(0)
  • 2020-12-31 06:29

    You can't. Look here for further reading on what the API could handle: YoutubeAPI
    If you could get an InputStream on that, Google won't get any money for advertisement at all.

    But you could parse the page of the video-url you got from the API and look for the real video-link inside the flash tags.

    0 讨论(0)
  • 2020-12-31 06:37
    /**
     * 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>
     */
    
    0 讨论(0)
提交回复
热议问题