I am trying to play youtube video in exoplayer but here is some confusion I don't know what is DASH url, I have only real youtube url like "https://www.youtube.com/watch?v=v1uyQZNg2vE" , I have no idea how to generate dash url form real url.
Dash Url:
new Sample("Google Glass",
"http://www.youtube.com/api/manifest/dash/id/bf5bb2419360daf1/source/youtube?"
+ "as=fmp4_audio_clear,fmp4_sd_hd_clear&sparams=ip,ipbits,expire,as&ip=0.0.0.0&"
+ "ipbits=0&expire=19000000000&signature=255F6B3C07C753C88708C07EA31B7A1A10703C8D."
+ "2D6A28B21F921D0B245CDCF36F7EB54A2B5ABFC2&key=ik0", DemoUtil.TYPE_DASH),
Real Url :
https://www.youtube.com/watch?v=v1uyQZNg2vE
ExoPlayer is the video player running in Android YouTube, Netflix, Amazon media player for Prime, HotStar, and many other popular and robust apps. Good documentation and tutorials. It's free!
I've written a class that retrieves actual YouTube video streaming URL for format like DASH and HLS using http://www.youtube.com/get_video_info?&video_id=[video_id]&el=info&ps=default&eurl=&gl=US&hl=en url with video ID as described by Karim Abdell Salam. I have also tested the URL in an app that uses ExoPlayer and it works:
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.ProtocolException;
import java.net.URL;
import java.net.URLDecoder;
import java.util.Map;
import java.util.TreeMap;
/**
* Represents youtube video information retriever.
*/
public class YouTubeVideoInfoRetriever
{
private static final String URL_YOUTUBE_GET_VIDEO_INFO = "http://www.youtube.com/get_video_info?&video_id=";
public static final String KEY_DASH_VIDEO = "dashmpd";
public static final String KEY_HLS_VIDEO = "hlsvp";
private TreeMap<String, String> kvpList = new TreeMap<>();
public void retrieve(String videoId) throws IOException
{
String targetUrl = URL_YOUTUBE_GET_VIDEO_INFO + videoId+"&el=info&ps=default&eurl=&gl=US&hl=en";
SimpleHttpClient client = new SimpleHttpClient();
String output = client.execute(targetUrl, SimpleHttpClient.HTTP_GET, SimpleHttpClient.DEFAULT_TIMEOUT);
parse(output);
}
public String getInfo(String key)
{
return kvpList.get(key);
}
public void printAll()
{
System.out.println("TOTAL VARIABLES=" + kvpList.size());
for(Map.Entry<String, String> entry : kvpList.entrySet())
{
System.out.print( "" + entry.getKey() + "=");
System.out.println("" + entry.getValue() + "");
}
}
private void parse(String data) throws UnsupportedEncodingException
{
String[] splits = data.split("&");
String kvpStr = "";
if(splits.length < 1)
{
return;
}
kvpList.clear();
for(int i = 0; i < splits.length; ++i)
{
kvpStr = splits[i];
try
{
// Data is encoded multiple times
kvpStr = URLDecoder.decode(kvpStr, SimpleHttpClient.ENCODING_UTF_8);
kvpStr = URLDecoder.decode(kvpStr, SimpleHttpClient.ENCODING_UTF_8);
String[] kvpSplits = kvpStr.split("=", 2);
if(kvpSplits.length == 2)
{
kvpList.put(kvpSplits[0], kvpSplits[1]);
}
else if(kvpSplits.length == 1)
{
kvpList.put(kvpSplits[0], "");
}
}
catch (UnsupportedEncodingException ex)
{
throw ex;
}
}
}
public static class SimpleHttpClient
{
public static final String ENCODING_UTF_8 = "UTF-8";
public static final int DEFAULT_TIMEOUT = 10000;
public static final String HTTP_GET = "GET";
public String execute(String urlStr, String httpMethod, int timeout) throws IOException
{
URL url = null;
HttpURLConnection conn = null;
InputStream inStream = null;
OutputStream outStream = null;
String response = null;
try
{
url = new URL(urlStr);
conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(timeout);
conn.setRequestMethod(httpMethod);
inStream = new BufferedInputStream(conn.getInputStream());
response = getInput(inStream);
}
finally
{
if(conn != null && conn.getErrorStream() != null)
{
String errorResponse = " : ";
errorResponse = errorResponse + getInput(conn.getErrorStream());
response = response + errorResponse;
}
if (conn != null)
{
conn.disconnect();
}
}
return response;
}
private String getInput(InputStream in) throws IOException
{
StringBuilder sb = new StringBuilder(8192);
byte[] b = new byte[1024];
int bytesRead = 0;
while (true)
{
bytesRead = in.read(b);
if (bytesRead < 0)
{
break;
}
String s = new String(b, 0, bytesRead, ENCODING_UTF_8);
sb.append(s);
}
return sb.toString();
}
}
}
Here is the test code:
public static void main(String[] args)
{
String youTubeVideoID = "v1uyQZNg2vE";
YouTubeVideoInfoRetriever retriever = new YouTubeVideoInfoRetriever();
try
{
retriever.retrieve(youTubeVideoID);
System.out.println(retriever.getInfo(YouTubeVideoInfoRetriever.KEY_DASH_VIDEO));
}
catch (IOException e)
{
e.printStackTrace();
}
}
I had the same issue but i finally found the simplest solution and its working so good
First you need to call this url..
HTTP GET: https://www.youtube.com/get_video_info?&video_id=[video_id]&el=info&ps=default&eurl=&gl=US&hl=en
and don't forget to change the last id with the target one.
-just paste your data and press decode a several times to ensure it decoded well
finally search for a key called dashmpd
Or use this Simple Solution
private void extractYoutubeUrl() {
@SuppressLint("StaticFieldLeak") YouTubeExtractor mExtractor = new YouTubeExtractor(this) {
@Override
protected void onExtractionComplete(SparseArray<YtFile> sparseArray, VideoMeta videoMeta) {
if (sparseArray != null) {
playVideo(sparseArray.get(17).getUrl());
}
}
};
mExtractor.extract(mYoutubeLink, true, true);
implementation 'com.github.HaarigerHarald:android-youtubeExtractor:v1.7.0'
You will have to get the HTTP response from the youtube URL (in your case real URL) and then search for the section "url_encoded_fmt_stream_map". In that section you will get a URI which needs to be decoded twice to get the DASH URL you are looking for.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With