流式传输到VideoView只能在使用三星手机时在Wifi上播放

时间:2012-01-30 20:21:37

标签: android streaming android-videoview

我正在使用以下库将YouTube视频流式传输到Android应用程序。

http://code.google.com/p/android-youtube-player/source/browse/trunk/OpenYouTubeActivity/src/com/keyes/youtube/OpenYouTubePlayerActivity.java?r=3

我成功地通过3G和Wifi在HTC和摩托罗拉手机上播放视频。但是,在三星Galaxy(Epic 4G)和三星Galaxy II手机上,我只能使用Wifi播放。 3G给了我这个错误:“无法播放视频。抱歉,此视频无法播放。”

我尝试过强制低质量的YouTube流媒体,但这并没有帮助。我在日志中看到在两种情况下都调用了Start()(3G / Wifi)。这是VideoView的问题吗?有解决方法吗?

修改2

视频来自YouTube API。我尝试使用嵌入式和普通流,以及可用的最低质量流(每个视频不同)。此外,我不认为这是一个编码问题,因为相同的视频使用Wifi正确播放。

修改1

无论使用Wifi播放更多视频还是不使用3G,我也会收到以下输出。

01-30 15:22:38.305: E/MediaPlayer(3831): error (1, -1)
01-30 15:22:38.305: E/MediaPlayer(3831): callback application
01-30 15:22:38.305: E/MediaPlayer(3831): back from callback
01-30 15:22:38.309: E/MediaPlayer(3831): Error (1,-1)

根据这个Link,这些错误意味着以下(我认为):

/*
 Definition of first error event in range (not an actual error code).
 */
const PVMFStatus PVMFErrFirst = (-1);
/*
 Return code for general failure
 */
const PVMFStatus PVMFFailure = (-1);
/*

/*
 Return code for general success
 */
const PVMFStatus PVMFSuccess = 1;
/*

进一步增加了混乱。

3 个答案:

答案 0 :(得分:4)

是的,正如您所想,这是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的文件中,并将该文件设置为source的{​​{1}}。我将编写一些代码片段来了解我的方法:

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(); } } 在文件结束前停止播放时会出现另一个问题,因为文件中没有足够的缓冲。为此,您需要设置VideoView,如果您不在视频的末尾,则应该从最后一个位置重新开始视频播放:

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()

我认为必须对此代码进行一些修改和改编,它可能不是最好的方法,但它帮助了我,我找不到任何替代方案。

答案 1 :(得分:1)

我已经用自己的方式解决了这个问题。每次都读你的日志猫。如果你有了

Error (1,-1) 

这意味着你将获得sorry,this video can not play message。所以在这种情况下完成该活动,给出自定义进度条并下载视频。然后下载后将其保存在临时文件夹中然后播放。播放后删除该文件夹。

阅读log cat ---

 try {
  Process process = Runtime.getRuntime().exec("logcat -d");
  BufferedReader bufferedReader = new BufferedReader(
  new InputStreamReader(process.getInputStream()));
   StringBuilder log=new StringBuilder();
  String line;
  while ((line = bufferedReader.readLine()) != null) {
    log.append(line);
  }
} catch (IOException e) {
}

也阅读此答案。虽然只是用户体验没有链接到应用程序。但有时在默认应用程序中也会出现

即使我有完整的3G网络覆盖,大量视频也会说“抱歉,此视频无法播放”。有一天,我对此感到很生气,我只是按下'Okay'来消除该消息,然后再次按下视频,只看到“抱歉,此视频无法播放”的消息。我重复这个过程(在我的盲目愤怒中),但最终,经过大约5次尝试,视频决定奇迹般地发挥!

这种方法每次都适合我。大多数视频都不想第一次播放,但最终如果我只是坚持不懈,并且一直告诉它即使它告诉我“不能”播放视频,它也会播放!虽然,有些视频我不得不按'好',按视频,按'好',按视频等...等20次才真正决定播放。那些时候,我已经非常接近拿起我的手机并把它扔到地板上,因为我对你的工作方式有多糟糕。

我希望有办法解决这个问题。似乎没有人想出一个解决方案。每个人都说“噢,我有同样的问题”,但没有人做出任何贡献。 GOOGLE,在你的手机上解决这个问题。在全球范围内,这款手机正在全球范围内发挥作用。

答案 2 :(得分:0)

此消息通常来自视频的不适当编码(“无法播放视频。抱歉此视频无法播放。”)我在视频方面挣扎了一段时间,现在正确的编码视频在所有经过测试的设备上播放,甚至使用Wifi或3G时。如果你想知道如何编码视频,请让他们知道。为了播放视频,我使用了android sdk apis中的演示,它完美无瑕。