是的,正如您所想的那樣,這是VideoView
中的問題,類似的問題也出現在MediaPlayer
中,並且我遇到過類似和奇怪的問題,當我只在3G上播放視頻時遇到問題,不在Wi-Fi上。這通常發生在2.1和2.2左右的設備上,但不是像我目前看到的那樣在更高的API級別上發生。
所以,我可以推薦是做到以下幾點:
首先檢查是否正在運行的設備可以是一種可以有問題,這樣的事情:
//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
}
}
因此,這是最簡單的一部分,檢測運行中的設備在流式傳輸視頻時是否存在問題。現在,我所做的也可能對您有所幫助的是,將Youtube中的視頻緩存在SDCard
的文件中,並將該文件設置爲您的VideoView
的source
。我會寫一些代碼片段,看看我的做法是如何:當VideoView
已經停止文件結束前打會出現
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();
}
}
另一個問題,因爲沒有足夠的是文件的緩衝。爲此,您需要設置一個onCompletionListener()
,如果你是不是在視頻的結尾,則應該從最後一個位置再次啓動視頻播放:
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();
}
}
最後,當然GetYoutubeFile
線程啓動在onCreate()
方法:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//init views,player,etc
new GetYoutubeFile().start();
}
一些修改和調整,我認爲將有此代碼來完成,它可能不是最好的方法,但它幫助了我,我找不到任何替代品。
似乎這個問題影響[其他設備](http://code.google.com/p/android-youtube-player/issues/detail?id=7) – Zakaria 2012-01-30 20:27:13
@Zakaria啊,是的。謝謝你指出。 – 2012-01-30 20:32:55
你能告訴我們你的設備的API級別是什麼?這項工作,並沒有奏效。 – 2012-02-14 22:23:52