I'm developing an Android app that can parse both the Youtube and Dailymotion webpages,and render its URL of videos, but the buffering speed is not stable.
Sometimes, the video is buffered fast via its Website native player, but it is buffered slow in my Android Videoview.
How can I fix the problem, and what kind of difference is there between these two ways to play Video?
private class isConnected extends AsyncTask<String, Void, Boolean> {
Boolean result;
public isConnected(Boolean r)
{
result = r;
}
protected Boolean doInBackground(String... params) {
HttpClient client = new DefaultHttpClient();
String getURL = params[0];
HttpGet get = new HttpGet(getURL);
HttpResponse responseGet = null;
try {
responseGet = client.execute(get);
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
Toast.makeText(getBaseContext(), "Error:" + e.getMessage(), Toast.LENGTH_LONG).show();
return false;
} catch (IOException e) {
// TODO Auto-generated catch block
//e.printStackTrace();
Toast.makeText(getBaseContext(), "Error:" + e.getMessage(), Toast.LENGTH_LONG).show();
return false;
}
if(responseGet.getStatusLine().getStatusCode() == HttpStatus.SC_OK)
result = true;
else
result = false;
return result;
}
protected void onPostExecute(Boolean r) {
// here you have the result
result = r;
}
}
VideoView videoView;
String URL;
videoView.setVideoPath(URL);
myVideoView.setOnPreparedListener(
new OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer arg0) {
arg0.setOnBufferingUpdateListener(new OnBufferingUpdateListener(){
#Override
public void onBufferingUpdate(MediaPlayer mp, int percent) {
// TODO Auto-generated method stub
Log.d("123","Buffer Percentage = " + percent);
}});
// TODO Auto-generated method stub
new isConnected(video_ready).execute(URL);
if (!video_ready)
{
progDailog.dismiss();
AlertDialog.Builder alert = new AlertDialog.Builder(HomeActivity.this);
alert.setTitle("Warning").setMessage("The URL of video is incorrect.").setNeutralButton("OK", null);
alert.create().show();
}
if (progDailog.isShowing())
{
progDailog.dismiss();
}
videoView.start();
}
});
Related
Not very easy to explain:
I have this app for streaming online radio. The problem was first with m3u format (which android somehow cannot normally stream like pls), so I have to parse the url with this ParserM3UToURL (that I found somewhere)... like this:
Uri u = Uri.parse(ParserM3UToURL.parse(STREAM_URL, sdkVersion, c));
player = MediaPlayer.create(c, u);
Mostly it works ok but it has one bug...
I'm testing this on two devices one old 2.2.2. (api level 17), other 4.3 (api level 23). Older device works fine. It can stream radio over wifi or mobile data, but the newer device has some problem with streaming over mobile data (on wifi it works ok). The application crashes because the parse function returns null: http://pastebin.com/ghbAqGzM
And I assume there are many more phones with 4.x than 2.x android. Which of course is very painful for me. Somehow I have to fix this.. So I really hope somebody will have some clue about this. I hope my explanation was not to confusing...
This is the ParserM3UToURL.parse() function:
public static String parse(String paramString, int sdkVersion, Context c)
{
try
{
StrictModeWrapper.init(c);
HttpURLConnection localHttpURLConnection = (HttpURLConnection)new URL(paramString).openConnection();
InputStream localInputStream = localHttpURLConnection.getInputStream();
BufferedReader localBufferedReader = new BufferedReader(new InputStreamReader(localInputStream));
StringBuffer localStringBuffer = new StringBuffer();
while (true)
{
String str = localBufferedReader.readLine();
if (str == null)
{
localHttpURLConnection.disconnect();
localBufferedReader.close();
localInputStream.close();
break;
}
if (str.contains("http"))
{
localHttpURLConnection.disconnect();
localBufferedReader.close();
localInputStream.close();
return str;
}
localStringBuffer.append(str);
}
}
catch (Exception e)
{
e.printStackTrace();
}
return null;
}
Below is what i worked on to stream radio (m3Urls). The example below uses a service. When the service is started, the url is parsed. Note that in the onPostExecute, parsed file is prepared. Once the file is prepared(completed buffering), the file is played/started and stopped upon completion.
public class BackgroundRadioService extends Service implements
OnCompletionListener, OnPreparedListener{
MediaPlayer mediaPlayer;
#Override
public void onCreate() {
mediaPlayer = new MediaPlayer();
mediaPlayer.setOnCompletionListener(this);
mediaPlayer.setOnPreparedListener(this);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
parseM3uUrlAndPrepare("http://listen.radionomy.com/andalousse.m3u");
return START_STICKY;
}
private void parseM3uUrlAndPrepare(final String url){
AsyncTask<String, Integer, String> asyn = new AsyncTask<String, Integer, String>(){
HttpClient httpClient;
HttpGet getRequest;
HttpResponse httpResponse = null;
String filePath = "";
#Override
protected void onPreExecute() {
super.onPreExecute();
httpClient = new DefaultHttpClient();
getRequest = new HttpGet(url);
}
#Override
protected String doInBackground(String... params) {
try {
httpResponse = httpClient.execute(getRequest);
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(httpResponse != null)
if (httpResponse.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
// ERROR MESSAGE
} else {
InputStream inputStream = null;
try {
inputStream = httpResponse.getEntity().getContent();
} catch (IllegalStateException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
String line;
try {
while ((line = bufferedReader.readLine()) != null) {
//Log.v("PLAYLISTLINE", "ORIG: " + line);
if (line.startsWith("#")) { // Metadata
} else if (line.length() > 0) {
filePath = "";
if (line.startsWith("http://")) { // Assume it's a full URL
filePath = line;
} else { // Assume it's relative
try{
filePath = getRequest.getURI().resolve(line).toString();
}catch(IllegalArgumentException e){
}catch(Exception e){
}
}
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
inputStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return filePath;
}
#Override
protected void onPostExecute(String filePath) {
try {
mediaPlayer.setDataSource(filePath);
mediaPlayer.prepareAsync(); //this will prepare file a.k.a buffering
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
};
asyn.execute("");
}
#Override
public void onPrepared(MediaPlayer mp) {
// TODO Auto-generated method stub
mediaPlayer.start();
}
#Override
public void onCompletion(MediaPlayer mp) {
mediaPlayer.stop();
}
}//end of Service class declaration
Note: This ignores playlists hence assumes the m3u parsed will return only one file. Let me know if you would like to handle playlists so I modify my answer :)
I solved it thanks to this question's comments: POST request failing when in 3G
The problem was actually with proxies on 3G. So if proxies are disabled, no weird http requests.
I modified my code a little. Thanks to Nana's answer I no longer need a m3u parser. I also no longer use HttpClient but HttpURLConnection instead. So when calling URL.openConnection() I add the Proxy.NO_PROXY parameter to that function and bam!
So the solution is "use HttpURLConnection not HttpClient and add NO_PROXY parameter":
conn = (HttpURLConnection) the_url.openConnection( Proxy.NO_PROXY );
I have written a simple code on JSON Parsing using AsyncTask. I'm just displaying the response in TextView. I don't know whether it is right or wrong. Its working on GingerBread and showing NetworkOnMainThreadException on JellyBean. If I use StrictMode, its working on JellyBean and getting force close on GingerBread. How to write the code which support above Android 3.0 and below Android 3.0.
public class MainActivity extends Activity {
TextView tv;
Button b;
InputStream is = null;
DefaultHttpClient client;
HttpGet get;
HttpResponse response;
HttpEntity entity;
StringBuffer buffer;
#SuppressLint("NewApi")
#TargetApi(Build.VERSION_CODES.GINGERBREAD)
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
// StrictMode.setThreadPolicy(policy);
tv = (TextView) findViewById(R.id.texty);
b = (Button) findViewById(R.id.buttonGET);
b.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
MyOperation mytask = new MyOperation();
mytask.execute();
}
});
}
private class MyOperation extends AsyncTask<String, Void, String> {
ProgressDialog dialog = new ProgressDialog(MainActivity.this);
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
dialog.setMessage("Loading...");
dialog.show();
}
#Override
protected String doInBackground(String... params) {
// TODO Auto-generated method stub
client = new DefaultHttpClient();
get = new HttpGet("http://www.google.com");
try {
response = client.execute(get);
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
entity = response.getEntity();
try {
is = entity.getContent();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
dialog.dismiss();
BufferedReader reader = new BufferedReader(
new InputStreamReader(is));
StringBuffer buffer = new StringBuffer();
String line = null;
do {
try {
line = reader.readLine();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
buffer.append(line);
} while (line != null);
tv.setText(buffer);
}
}
}
public class MainActivity extends Activity {
TextView tv;
Button b;
InputStream is = null;
DefaultHttpClient client;
HttpGet get;
HttpResponse response;
HttpEntity entity;
StringBuffer buffer;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//StrictMode.ThreadPolicy policy = new
// StrictMode.setThreadPolicy(policy);
tv = (TextView) findViewById(R.id.texty);
b = (Button) findViewById(R.id.buttonGET);
b.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
MyOperation mytask = new MyOperation();
mytask.execute();
}
});
}
private class MyOperation extends AsyncTask<String, Void, String> {
ProgressDialog dialog = new ProgressDialog(MainActivity.this);
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
dialog.setMessage("Loading...");
dialog.show();
}
#Override
protected String doInBackground(String... params) {
StringBuffer buffer = new StringBuffer();
// TODO Auto-generated method stub
client = new DefaultHttpClient();
get = new HttpGet("http://www.google.com");
try {
response = client.execute(get);
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
entity = response.getEntity();
try {
is = entity.getContent();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
BufferedReader reader = new BufferedReader(
new InputStreamReader(is));
String line = null;
do {
try {
line = reader.readLine();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
buffer.append(line);
} while (line != null);
return buffer.tostring();
}
#Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
dialog.dismiss();
tv.setText(result);
}}
}
otherwise you are running the read line operation in main thread
Make the InputStream is and Entity entity local field variables in the doInBackground() as return as result the string that you wanna set on the TextView...and on the onPostExecute() you just get the result (the string) and set it in the TextView straight on.
You should read inputStream data in doInBackground function, not in the onPostExecute. So construct StringBuffer in doInBackground append all lines to it and return StringBuffer.toString as result. In onPostExecute you will get what string as parameter.
I need to download a file from internet to update some resources files in the path
"/data/data/" + context.getPackageName() + "/databases/"
the method
public static void updateDB(){
removeOldCopies();
//how to download a file in a specific directory without open browser????
}
should perform this action without user intervention, showing only a progress dialog
How could I do this?
You can use AsyncTask to show a Progress Dialog on the PreExecute() method and hide/dismiss it in the PostExecute() method.
ProgressDialog prog = new ProgressDialog(this); // Create Progress Dialog
private class DownloadFile extends AsyncTask<Void, Integer, Void>{
#Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
//Display progressDialog before download starts
prog.show();
}
#Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
prog.hide(); //Hide Progress Dialog else use dismiss() to dismiss the dialog
}
#Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
InternetManager in = new InternetManager("http://url-to-download");
in.fileRequest();
return null;
}
}
in.fileRequest() will give you the file that you intent to download, Then use FileOutputStream.write(bytes[]) to write it into a file.
And finally call the AsyncTask through,
DownloadFile dd = new DownloadFile();
dd.execute();
InternetManager class which performing internet releted task.
public class InternetManager {
HttpClient httpclient;
HttpGet httpget;
HttpResponse httpresponse;
HttpEntity httpentity;
String url;
String response = null;
byte[] data = null;
public InternetManager(String url) {
this.url = url;
}
public byte[] fileRequest() {
httpclient = new DefaultHttpClient();
httpget = new HttpGet(url);
try {
httpresponse = httpclient.execute(httpget);
httpentity = httpresponse.getEntity();
data = EntityUtils.toByteArray(httpentity);
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Log.v("", "File downloaded URL: " + url);
return data;
}
}
Android Media Player:
I'm able to play .mp3 file from URL.
While playing .pls getting eroor.
Code:
try{
String url=".pls url";
mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setDataSource(url);
mediaPlayer.prepare();
mediaPlayer.start();
}catch(Exception
System.out.println("## Exception while playing: "+e);
mediaPlayer .release();
mediaPlayer = null;
}
Error:
09-12 12:44:04.026: E/MediaPlayer(704): error (1, -2147483648)
09-12 12:44:04.026: I/System.out(704): ## Exception while playing: java.io.IOException: Prepare failed.: status=0x1
If by pls you mean playlist information file, then mediaplayer cannot handle pls files.
.pls files are not media files. So you cannot play .pls files. Usually .pls are handled by the app and app extracts the information from the pls file and play the music file to which pls is pointing to.
String musicUlrPath;
LinkedList<String> streamingUrlList;
streamingUrlList=new LinkedList<String>();
ExecuteArrayList executeArrayList=new ExecuteArrayList();
executeArrayList.execute("blank");
class ExecuteArrayList extends AsyncTask<String, String, String>
{
#Override
protected String doInBackground(String... params) {
// TODO Auto-generated method stub
try {
streamingUrlList=getStreamingUrl(pathFromJson);//you are geting path during json response
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
musicUlrPath=(streamingUrlList.get(0));
}
}
public LinkedList<String> getStreamingUrl(String url) {
Log.i(LOGTAG, "get streaming url");
final BufferedReader br;
String murl = null;
LinkedList<String> murls = null;
try {
URLConnection mUrl = new URL(url).openConnection();
br = new BufferedReader(
new InputStreamReader(mUrl.getInputStream()));
murls = new LinkedList<String>();
while (true) {
try {
String line = br.readLine();
if (line == null) {
break;
}
murl = parseLine(line);
if (murl != null && !murl.equals("")) {
murls.add(murl);
}
} catch (IOException e) {
e.printStackTrace();
}
}
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Log.i(LOGTAG, "url to stream :" + murl);
return murls;
}
private String parseLine(String line) {
if (line == null) {
return null;
}
String trimmed = line.trim();
if (trimmed.indexOf("http") >= 0) {
return trimmed.substring(trimmed.indexOf("http"));
}
return "";
}
now set the extracted path
mediaPlayer.setDataSource(musicUlrPath);
Extract pls file in notepad , It will show like this
playlist]
File1=Alternative\everclear -URL
Title1=Everclear - So Much For The Afterglow
Length1=233
File2=Comedy\Weird Al - Everything You Know Is Wrong.mp3
.
.
NumberOfEntries=5
Version=2.
Use that URL in Media player.It will work.
I am currently making an app to go with my online radio site, I am coding it with Android 2.2 (API 8) and I have got the Shoutcast Stream working with two buttons.
Here is the code on my main class:
public class GrooveOfMusicRadioActivity extends Activity {
/** Called when the activity is first created. */
MediaPlayer mediaPlayer;
Button start, stop;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
start = (Button) findViewById(R.id.button1);
stop = (Button) findViewById(R.id.button2);
start.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
mediaPlayer.start();
}
});
stop.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
mediaPlayer.pause();
}
});
String url = "http://67.212.165.106:8161"; // your URL here
mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setAudioStreamType(AudioManager.STREAM_NOTIFICATION);
try {
mediaPlayer.setDataSource(url);
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
mediaPlayer.prepare();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
So I was wondering so how do I receive the stream title,song,artist etc.. and make it appear
The main XML is in a relative layout
Thanks, I am a total noob when it comes to programming.
Thanks mark :)
I just had to get meta data myself, I basically did the same stuff from: Pulling Track Info From an Audio Stream Using PHP. A lot of data is in the headers so you can use those, but all I wanted was the Stream Title, so thats what I got.
Activity mainAct = this;
public void getNowPlaying(View v) {
Log.w("getNowPlaying", "fired");
new Thread(new Runnable() {
public void run() {
String title = null, djName = null;
try {
URL updateURL = new URL(YOUR_STREAM_URL_HERE);
URLConnection conn = updateURL.openConnection();
conn.setRequestProperty("Icy-MetaData", "1");
int interval = Integer.valueOf(conn.getHeaderField("icy-metaint")); // You can get more headers if you wish. There is other useful data.
InputStream is = conn.getInputStream();
int skipped = 0;
while (skipped < interval) {
skipped += is.skip(interval - skipped);
}
int metadataLength = is.read() * 16;
int bytesRead = 0;
int offset = 0;
byte[] bytes = new byte[metadataLength];
while (bytesRead < metadataLength && bytesRead != -1) {
bytesRead = is.read(bytes, offset, metadataLength);
offset = bytesRead;
}
String metaData = new String(bytes).trim();
title = metaData.substring(metaData.indexOf("StreamTitle='") + 13, metaData.indexOf(" / ", metaData.indexOf("StreamTitle='"))).trim();
djName = metaData.substring(metaData.indexOf(" / ", metaData.indexOf("StreamTitle='")) + 3, metaData.indexOf("';", metaData.indexOf("StreamTitle='"))).trim();
Log.w("metadata", metaData);
is.close();
} catch (MalformedURLException e) { e.printStackTrace();
} catch (IOException e) { e.printStackTrace(); }
final String titleFin = title;
final String djNameFin = djName;
mainAct.runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(mainAct, titleFin + "\n" + djNameFin, Toast.LENGTH_SHORT).show();
}
});
}
}).start();
}
What you're using to play the stream has no knowledge of (and doesn't care about) the metadata. You're going to have to deal with that separately.
See these posts for something you can easily adapt to Android:
Pulling Track Info From an Audio Stream Using PHP
http://www.smackfu.com/stuff/programming/shoutcast.html