diff --git a/res/layout/main_activity.xml b/res/layout/main_activity.xml
index 0e13cd6..6f24bf7 100644
--- a/res/layout/main_activity.xml
+++ b/res/layout/main_activity.xml
@@ -11,16 +11,14 @@
Alerta! Llibreries de Vitamio no instal·lades!
Alerta!
Item type
+ Buffering...
\ No newline at end of file
diff --git a/src/com/upc/pbe/upcnews/Directoris.java b/src/com/upc/pbe/upcnews/Directoris.java
index 301c3dc..5cc7f2f 100644
--- a/src/com/upc/pbe/upcnews/Directoris.java
+++ b/src/com/upc/pbe/upcnews/Directoris.java
@@ -6,8 +6,6 @@ import java.util.ArrayList;
import java.util.concurrent.ExecutionException;
import android.app.Activity;
-import android.app.DownloadManager;
-import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
@@ -61,12 +59,10 @@ public class Directoris extends Activity implements OnItemClickListener
}
catch (InterruptedException e)
{
- // TODO Auto-generated catch block
e.printStackTrace();
}
catch (ExecutionException e)
{
- // TODO Auto-generated catch block
e.printStackTrace();
}
catch (IOException e)
@@ -106,8 +102,7 @@ public class Directoris extends Activity implements OnItemClickListener
ArrayList m3u8parsed = p.parseFile(playlist);
Log.d(TAG, "Parsing completat");
//Creem un gestor HLS
- DownloadManager manager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
- HLS h = new HLS(m3u8parsed,((UpcApp)getApplication()).getLocalPath(), manager);
+ HLS h = new HLS(m3u8parsed,((UpcApp)getApplication()).getLocalPath());
((UpcApp)getApplication()).setHLS(h);
//Iniciem la reproduccio
Intent mIntent = new Intent(this, VideoActivity.class);
@@ -142,12 +137,10 @@ public class Directoris extends Activity implements OnItemClickListener
}
catch (InterruptedException e1)
{
- // TODO Auto-generated catch block
e1.printStackTrace();
}
catch (ExecutionException e1)
{
- // TODO Auto-generated catch block
e1.printStackTrace();
}
}
diff --git a/src/com/upc/pbe/upcnews/HLS.java b/src/com/upc/pbe/upcnews/HLS.java
index 8c30f23..f914220 100644
--- a/src/com/upc/pbe/upcnews/HLS.java
+++ b/src/com/upc/pbe/upcnews/HLS.java
@@ -1,20 +1,27 @@
package com.upc.pbe.upcnews;
+import io.vov.vitamio.widget.VideoView;
+
+import java.io.BufferedInputStream;
import java.io.File;
+import java.io.FileOutputStream;
import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
import java.util.ArrayList;
-import android.app.DownloadManager;
-import android.app.DownloadManager.Request;
+import android.app.AlertDialog;
import android.content.Context;
import android.net.TrafficStats;
-import android.net.Uri;
+import android.os.AsyncTask;
import android.util.Log;
+import android.view.LayoutInflater;
+import android.widget.Toast;
//Gestor del protocol HTTP Live Streaming
public class HLS
{
-
+ private static long TRIGGER_PLAY;
private static final String TAG = "HLS";
private ArrayList videos;
private ArrayList segments;
@@ -24,11 +31,15 @@ public class HLS
private int currentSegment;
private boolean endReached;
private String localFolder;
- private DownloadManager dm;
private BandwidthMeasurer bm;
+ private boolean started;
+ private boolean ended;
+ private long totalDownloaded;
+ private VideoView video;
+ private VideoActivity vActivity;
- public HLS(ArrayList parsed, String localFolder, DownloadManager manager)
+ public HLS(ArrayList parsed, String localFolder)
{
// Neteja el directori i inicialitza les variables
File dir = new File(localFolder);
@@ -45,8 +56,47 @@ public class HLS
endReached = false;
this.localFolder = localFolder;
bm = new BandwidthMeasurer();
+ started = ended = false;
+ totalDownloaded = 0;
}
+ public void setBufferSize()
+ {
+ /*
+ * Supondremos todos los segmentos de misma duración
+ */
+ if(qualities.get(currentQuality).getQuality() == -1)
+ {
+ /*
+ * No nos dicen la calidad, la pondremos al conocer la longitud del primer segmento
+ */
+ TRIGGER_PLAY = -1;
+ }
+ else
+ {
+ //15 segundos de cancha para empezar
+ TRIGGER_PLAY = (long) (15 * qualities.get(currentQuality).getQuality()/8e3);
+ }
+
+ }
+
+ public void quitPlayer(VideoActivity v)
+ {
+ video.stopPlayback();
+ v.finish();
+ return;
+ }
+
+ public void setVideoViewer(VideoView v)
+ {
+ video = v;
+ }
+
+ public void setVideoActivity(VideoActivity v)
+ {
+ vActivity = v;
+ }
+
public void loadVideo()
{
// Carrega la qualitat i, a partir d'aixo, el seguent segment
@@ -56,6 +106,7 @@ public class HLS
{
endReached = true;
}
+ setBufferSize();
}
public String next() throws IOException
@@ -71,59 +122,47 @@ public class HLS
}
Segment seg = segments.get(currentSegment++);
String path = localFolder+seg.getURL().substring(seg.getURL().lastIndexOf("/") + 1, seg.getURL().length());
- if(!new File(path).exists()) //Para qué bajarlo dos veces?
+ Log.d(TAG, seg.getName() + " " + seg.getURL());
+ return path;
+ }
+
+ public void updateQuality(long bps)
+ {
+ if ((bps <= qualities.get(currentQuality).getQuality()) && (bps != -1))
{
- Log.d(TAG, seg.getName() + " " + seg.getURL());
- long startTime = System.currentTimeMillis();
- long segmentBytes = TrafficStats.getTotalRxBytes();
- descarregarguardar(seg.getURL(), localFolder);
- double bps = bm.Measure(segmentBytes, startTime);
- Log.d(TAG, "Velocitat actual (KB/s): " + (bps / 8e3));
- if ((bps <= qualities.get(currentQuality).getQuality()) && (bps != -1))
+ int newQuality;
+ for(newQuality = 0; newQuality < qualities.size(); newQuality++)
{
- int newQuality;
- for(newQuality = 0; newQuality < qualities.size(); newQuality++)
- {
- if(bps >= qualities.get(newQuality).getQuality())
- {
- break;
- }
- }
- if(currentQuality != newQuality)
+ if(bps >= qualities.get(newQuality).getQuality())
{
- currentQuality = newQuality;
- currentVideo--; //Corregimos el del loadVideo()
- loadVideo(); //Cargamos la nueva calidad
+ break;
}
}
- else if((bps > qualities.get(currentQuality).getQuality()) && (bps != -1))
+ if(currentQuality != newQuality)
{
- int newQuality;
- for(newQuality = qualities.size()-1; newQuality > 0; newQuality--)
- {
- if(bps <= qualities.get(newQuality).getQuality())
- {
- newQuality--;
- break;
- }
- }
- if(currentQuality != newQuality)
+ currentQuality = newQuality;
+ currentVideo--; //Corregimos el del loadVideo()
+ loadVideo(); //Cargamos la nueva calidad
+ }
+ }
+ else if((bps > qualities.get(currentQuality).getQuality()) && (bps != -1))
+ {
+ int newQuality;
+ for(newQuality = qualities.size()-1; newQuality > 0; newQuality--)
+ {
+ if(bps <= qualities.get(newQuality).getQuality())
{
- currentQuality = newQuality;
- currentVideo--; //Corregimos el del loadVideo()
- loadVideo(); //Cargamos la nueva calidad
+ newQuality--;
+ break;
}
}
+ if(currentQuality != newQuality)
+ {
+ currentQuality = newQuality;
+ currentVideo--; //Corregimos el del loadVideo()
+ loadVideo(); //Cargamos la nueva calidad
+ }
}
- return path;
- }
-
- public void descarregarguardar(String url, String path)
- {
- Request req = new Request(Uri.parse(url));
- req.setVisibleInDownloadsUi(false);
- req.setDestinationUri(Uri.parse("file://"+path + url.substring(url.lastIndexOf("/")+1, url.length())));
- dm.enqueue(req);
}
public String previous() throws IOException
@@ -136,9 +175,127 @@ public class HLS
seg = segments.get(currentSegment++);
return localFolder + seg.getURL().substring(seg.getURL().lastIndexOf("/") + 1, seg.getURL().length());
}
-
- public void startDownloadManager(Context ctx)
+
+ public boolean hasEnded()
+ {
+ return ended;
+ }
+
+ public void buffer()
+ {
+ video.stopPlayback();
+ started = false;
+ }
+
+ public void downloadSegment(String url)
{
- dm = (DownloadManager) ctx.getSystemService("download");
+ DescarregaSegment ds = new DescarregaSegment(vActivity);
+ try
+ {
+ ds.execute(new URL(url));
+ }
+ catch (MalformedURLException e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ public class DescarregaSegment extends AsyncTask
+ {
+ final static String TAG = "DescarregaSegment";
+ private Context ctx;
+ private long bps;
+ AlertDialog alertDialog;
+
+ public DescarregaSegment(Context c)
+ {
+ ctx = c;
+ bps = 0;
+ AlertDialog.Builder builder = new AlertDialog.Builder(vActivity);
+ LayoutInflater inflater = vActivity.getLayoutInflater();
+ builder.setView(inflater.inflate(R.layout.buffering_dialog,null));
+ alertDialog = builder.create();
+ }
+
+
+ @Override
+ protected Long doInBackground(URL... urls)
+ {
+ if(!started)
+ {
+ alertDialog.show();
+ }
+ Long downloaded = Long.valueOf(0);
+ long startTime = System.currentTimeMillis();
+ long segmentBytes = TrafficStats.getTotalRxBytes();
+ Log.d(TAG, "Velocitat actual (KB/s): " + (bps / 8e3));
+ // Iniciem la connexi� i creem els Streams
+ try
+ {
+ FileOutputStream out = new FileOutputStream(localFolder + "video.ts");
+ BufferedInputStream in = new BufferedInputStream(urls[0].openStream());
+ Log.d(TAG, "\nDescarregant: \n");
+ Log.d(TAG, ">> URL: " + urls[0]);
+ byte data[] = new byte[102400];
+ int count;
+ while ((count = in.read(data)) != -1)
+ {
+ downloaded += count;
+ out.write(data, 0, count);
+ }
+ out.flush();
+ out.close();
+ in.close();
+ bps = (long) bm.Measure(segmentBytes, startTime);
+ Log.d(TAG, "Descarrega finalitzada");
+ }
+ catch(IOException e)
+ {
+ this.cancel(true);
+ Toast.makeText(ctx, e.getMessage(), Toast.LENGTH_LONG).show();
+ return Long.valueOf(-1);
+ }
+ return downloaded;
+ }
+ protected void onPostExecute(Long result)
+ {
+ totalDownloaded += result;
+ if(ended = true)
+ {
+ quitPlayer((VideoActivity) ctx);
+ }
+ if(TRIGGER_PLAY == -1)
+ {
+ long Bps = (long) (result/segments.get(currentSegment).getDuration());
+ TRIGGER_PLAY = 15*Bps/1000;
+ }
+ if(!started && totalDownloaded >= TRIGGER_PLAY)
+ {
+ alertDialog.dismiss();
+ started = true;
+ video.start();
+ video.requestFocus();
+ }
+ String newSegment = null;
+ try
+ {
+ updateQuality((long) bps);
+ newSegment = next();
+ }
+ catch(IOException e)
+ {
+ Toast.makeText(ctx, "No s'ha trobat el segment", Toast.LENGTH_LONG).show();
+ quitPlayer((VideoActivity) ctx);
+ }
+ if(newSegment.equals(null))
+ {
+ ended = true;
+ }
+ else
+ {
+ downloadSegment(newSegment);
+ }
+ return;
+ }
}
}
\ No newline at end of file
diff --git a/src/com/upc/pbe/upcnews/MainActivity.java b/src/com/upc/pbe/upcnews/MainActivity.java
index 9a90def..73ca1ad 100644
--- a/src/com/upc/pbe/upcnews/MainActivity.java
+++ b/src/com/upc/pbe/upcnews/MainActivity.java
@@ -21,7 +21,8 @@ import android.widget.TextView;
import android.widget.Toast;
//Finestra incial i activity principal del programa
-public class MainActivity extends Activity implements OnClickListener {
+public class MainActivity extends Activity implements OnClickListener
+{
private final static String TAG = "Main";
private static String html;
@@ -78,19 +79,18 @@ public class MainActivity extends Activity implements OnClickListener {
}
catch (InterruptedException e)
{
- // TODO Auto-generated catch block
e.printStackTrace();
}
catch (ExecutionException e)
{
- // TODO Auto-generated catch block
e.printStackTrace();
}
catch (MalformedURLException e)
{
Toast.makeText(this, "URL Malformada", Toast.LENGTH_LONG).show();
}
- if(!html.equals("")) {
+ if(!html.equals(""))
+ {
((UpcApp) getApplication()).setDesc(html);
startActivity(new Intent(this, Directoris.class));
}
diff --git a/src/com/upc/pbe/upcnews/ParentList.java b/src/com/upc/pbe/upcnews/ParentList.java
index 056df6e..a1748b3 100644
--- a/src/com/upc/pbe/upcnews/ParentList.java
+++ b/src/com/upc/pbe/upcnews/ParentList.java
@@ -5,7 +5,6 @@ import java.util.ArrayList;
public class ParentList
{
private String ID;
- private int currentQuality;
private String Type, Name;
private boolean Default; //Estos 3 ultimos son para los ext-x-media, los ext-x-stream lo IGNORAN
private ArrayList