Sí, como está pensando, este es un problema en VideoView
, problemas similares también aparecen en MediaPlayer
, y me he encontrado con problemas similares y extraños como los que tuvo, tuve problemas cuando el video solo se reprodujo en 3G y no en Wi-Fi. Esto generalmente ocurre en 2.1 y algunos dispositivos 2.2, pero no en niveles de API más altos como he visto hasta ahora.
Entonces, ¿qué puedo recomendar es hacer lo siguiente:
En primer lugar comprobar si el dispositivo en funcionamiento puede ser uno que puede tener problemas, algo como esto:
//Define a static list of known devices with issues
static List sIssueDevices=Arrays.asList(new String[]{"HTC Desire","LG-P500","etc"});
if(Build.VERSION.SDK_INT<9){
if(sIssueDevices.contains(Build.Device){
//This device may have issue in streaming, take appropriate actions
}
}
Así que esta fue la parte más simple, para detectar si el dispositivo en ejecución puede tener problemas al transmitir el video. Ahora, lo que hice y también puedo ayudarte, es almacenar el video de Youtube en un archivo en el archivo SDCard
y configurar ese archivo como source
para tu VideoView
. Voy a escribir algunos fragmentos de código para ver cómo era mi enfoque: surgirá
private class GetYoutubeFile extends Thread{
private String mUrl;
private String mFile;
public GetYotubeFile(String url,String file){
mUrl=url;
mFile=file;
}
@Override
public void run() {
super.run();
try {
File bufferingDir=new File(Environment.getExternalStorageDirectory()
+"/YoutubeBuff");
File bufferFile=new File(bufferingDir.getAbsolutePath(), mFile);
//bufferFile.createNewFile();
BufferedOutputStream bufferOS=new BufferedOutputStream(
new FileOutputStream(bufferFile));
URL url=new URL(mUrl);
URLConnection connection=url.openConnection();
connection.setRequestProperty("User-Agent", "Mozilla");
connection.connect();
InputStream is=connection.getInputStream();
BufferedInputStream bis=new BufferedInputStream(is,2048);
byte[] buffer = new byte[16384];
int numRead;
boolean started=false;
while ((numRead = bis.read(buffer)) != -1 && !mActivityStopped) {
//Log.i("Buffering","Read :"+numRead);
bufferOS.write(buffer, 0, numRead);
bufferOS.flush();
mBuffPosition += numRead;
if(mBuffPosition>120000 &&!started){
Log.e("Player","BufferHIT:StartPlay");
setSourceAndStartPlay(bufferFile);
started=true;
}
}
Log.i("Buffering","Read -1?"+numRead+" stop:"+mActivityStopped);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void setSourceAndStartPlay(File bufferFile) {
try {
mPlayer.setVideoPath(bufferFile.getAbsolutePath());
mPlayer.prepare();
mPlayer.start();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
Otra cuestión cuando el VideoView
ha dejado de jugar antes del final del archivo, porque no hay suficiente se reguló en el archivo.Para ello es necesario establecer un onCompletionListener()
y si no está al final del video, usted debe comenzar de nuevo la reproducción de vídeo desde la última posición:
public void onCompletion(MediaPlayer mp) {
mPlayerPosition=mPlayer.getCurrentPosition();
try {
mPlayer.reset();
mPlayer.setVideoPath(
new File("mnt/sdcard/YoutubeBuff/"+mBufferFile).getAbsolutePath());
mPlayer.seekTo(mPlayerPosition);
mPlayer.start();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
Al final, por supuesto, se inicia el hilo GetYoutubeFile
en el onCreate()
método:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//init views,player,etc
new GetYoutubeFile().start();
}
Algunas modificaciones y adaptación creo que tendrá que ser hecho por este código, y puede que no sea el mejor enfoque, pero me ayudó, y no pude encontrar ninguna alternativa.
Parece que este problema afecta a [otros dispositivos] (http://code.google.com/p/android-youtube-player/issues/detail?id=7) – Zakaria
@Zakaria Ah, sí. Gracias por señalar eso. –
¿Puede decirnos también cuáles son los niveles API de sus dispositivos? Ese trabajo y eso no funciona. –