流至VideoView只能使用三星手机的时候扮演的无线上网 [英] Streaming to VideoView only plays on Wifi when using Samsung phones

查看:147
本文介绍了流至VideoView只能使用三星手机的时候扮演的无线上网的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我用下面的库流YouTube视频到一个Android应用程序。

<一个href="http://$c$c.google.com/p/android-youtube-player/source/browse/trunk/OpenYouTubeActivity/src/com/keyes/youtube/OpenYouTubePlayerActivity.java?r=3">http://$c$c.google.com/p/android-youtube-player/source/browse/trunk/OpenYouTubeActivity/src/com/keyes/youtube/OpenYouTubePlayerActivity.java?r=3

我能够成功地通过3G和Wifi上播放视频HTC和摩托罗拉手机。然而,三星Galaxy(史诗4G)和三星Galaxy II手机,我只能通过WiFi播放。 3G给了我这个错误:。无法播放视频很抱歉,此视频无法播放

我试图迫使低质量的YouTube流媒体,但是这并没有帮助。我在日志中开始看到()被称为在两种情况下(3G / WIFI)。这是一个问题VideoView?有没有解决办法?

编辑2

视频会从YouTube API的到来。我已经使用嵌入式和正常数据流,以及提供最低的质量流(每个视频变的)尝试。另外,我不认为这是一个编码的问题,因为相同的视频播放正确使用WiFi。

修改1

我也收到下面的输出,无论羯羊视频的播放使用WiFi或者不使用3G。

  01-30 15:22:38.305:E / MediaPlayer的(3831):错误(1,-1)
01-30 15:22:38.305:E / MediaPlayer的(3831):回调应用
01-30 15:22:38.305:E / MediaPlayer的(3831):从回调回来
01-30 15:22:38.309:E / MediaPlayer的(3831):错误(1,-1)
 

根据该<一href="https://github.com/android/platform_external_opencore/blob/master/pvmi/pvmf/include/pvmf_return_$c$cs.h">Link,这些错误是指以下(我认为):

  / *
 在范围内第一个错误事件(不是一个实际的错误code)的定义。
 * /
常量PVMFStatus PVMFErrFirst =(-1);
/ *
 返回code一般失败
 * /
常量PVMFStatus PVMFFailure =(-1);
/ *

/ *
 返回code一般成功
 * /
常量PVMFStatus PVMFSuccess = 1;
/ *
 

进一步增加混乱。

解决方案

是的,如你所想,这是 VideoView 一个问题,类似的问题也出现在<像你一样code>的MediaPlayer ,我也遇到过类似的怪问题,我有问题时,该视频是只打了上3G,而不是无线网络连接。这通常发生在2.1和2.2的一些设备,但不能在更高层次的API,因为我已经看到了这么远。<​​/ P>

因此​​,我可以推荐是做到以下几点:

首先检查是否正在运行的设备可能是一个可以有问题,这样的事情:

  //定义已知设备有问题的静态列表
静态列表sIssueDevices = Arrays.asList(新的String [] {的HTC Desire,LG-P500,等});

如果(Build.VERSION.SDK_INT&10 9){
     如果(sIssueDevices.contains(Build.Device){
         //该设备可能有问题,流媒体,采取适当的行动
     }
}
 

因此​​,这是最简单的部分,以检测运行装置可以具有在流的视频的问题。现在,我做了什么,也可以帮助你,是缓冲从Youtube的视频在一个文件中的 SD卡,并设置文件作为 VideoView 。我会写一些code片段,看看我的方法怎么回事:

 私有类GetYoutubeFile继承Thread {
    私人字符串mUrl;
    私人字符串MFILE;
    公共GetYotubeFile(URL字符串,字符串文件){
        mUrl =网址;
        MFILE =文件;
    }

    @覆盖
    公共无效的run(){
        super.run();
        尝试 {

            文件bufferingDir =新的文件(Environment.getExternalStorageDirectory()
                    +/ YoutubeBuff);

            文件bufferFile =新的文件(bufferingDir.getAbsolutePath(),MFILE);
            //bufferFile.createNewFile();
            的BufferedOutputStream bufferOS =新的BufferedOutputStream(
                                      新的FileOutputStream(bufferFile));

            网址URL =新的URL(mUrl);
            URLConnection的连接= url.openConnection();
            connection.setRequestProperty(用户代理,Mozilla的);
            connection.connect();
            InputStream的是= connection.getInputStream();
            的BufferedInputStream双=新的BufferedInputStream(是,2048);

            byte []的缓冲区=新的字节[16384]
            INT numRead;
            布尔开始= FALSE;
            而((numRead = bis.read(缓冲))= -1放大器;!&安培;!mActivityStopped){
                //Log.i("Buffering","Read:+ numRead);
                bufferOS.write(缓冲液,0,numRead);
                bufferOS.flush();
                mBuffPosition + = numRead;
                如果(mBuffPosition&GT; 120000&安培;&安培;!开始){
                    Log.e(玩家,BufferHIT:StartPlay);
                    setSourceAndStartPlay(bufferFile);
                    开始= TRUE;
                }

            }
            Log.i(缓冲,读-1?+ numRead +一站式+ mActivityStopped);
        }赶上(MalformedURLException异常E){
            e.printStackTrace();
        }赶上(IOException异常E){
            e.printStackTrace();
        }
    }
}

公共无效setSourceAndStartPlay(文件bufferFile){
    尝试 {
        mPlayer.setVideoPath(bufferFile.getAbsolutePath());
        MPLAYER prepare()。
        mPlayer.start();
    }赶上(抛出:IllegalArgumentException E){
        e.printStackTrace();
    }赶上(IllegalStateException异常E){
        e.printStackTrace();
    }赶上(IOException异常E){
        e.printStackTrace();
    }
}
 

将出现另一个问题,当 VideoView 已停止文件结束前播放,因为没有足够的缓冲是在文件中。为此,您需要设置一个 onCompletionListener()键,如果你不是在视频的最后,你应该重新开始从最后一个位置的视频播放:

 公共无效onCompletion(MediaPlayer的MP){
    mPlayerPosition = mPlayer.getCurrentPosition();
    尝试 {
        mPlayer.reset();
        mPlayer.setVideoPath(
             新的文件(MNT / SD卡/ YoutubeBuff /+ mBufferFile).getAbsolutePath());
        mPlayer.seekTo(mPlayerPosition);
        mPlayer.start();
    }赶上(抛出:IllegalArgumentException E){
        e.printStackTrace();
    }赶上(IllegalStateException异常E){
        e.printStackTrace();
    }赶上(IOException异常E){
        e.printStackTrace();
    }

}
 

在最后,当然 GetYoutubeFile 线程开始在的onCreate()方法:

 公共无效的onCreate(包savedInstanceState){
    super.onCreate(savedInstanceState);
    //初始化意见,播放器等
    新GetYoutubeFile()启动();
}
 

一些修改和调整,我认为将有此code做,它可能不是最好的方法,但它帮助了我,我找不到任何办法。

I am using the following library to stream YouTube videos to an Android application.

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

I am successfully able to play videos on HTC and Motorola phones over 3G and Wifi. However, on Samsung Galaxy (Epic 4G) and Samsung Galaxy II phones I am only able to play using Wifi. 3G gives me this error: "Cannot play video. Sorry this video cannot be played."

I have tried forcing low quality YouTube streaming, but this did not help. I see in my log that Start() is being called in both cases (3G/Wifi). Is this an issue with VideoView? Is there a workaround?

Edit 2

The videos are coming from YouTube API. I have attempted using embedded and normal streams, as well as lowest quality stream available (varying per video). Also, I do not think it is an encoding issue since the same videos play correctly using Wifi.

Edit 1

I also receive the following output regardless of wether video plays using Wifi or does not using 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)

According to this Link, these errors means the following (I think):

/*
 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;
/*

Further adding confusion.

解决方案

Yes, as you are thinking, this is a issue in VideoView, similar issues also appear in MediaPlayer, and I've encountered similar and strange issues as you did, I had problems when the video was played only on 3G and not on Wi-Fi. This usually happens on 2.1 and some 2.2 devices, but not on higher API levels as I've seen so far.

So what I can recommend is do the following :

First check if the running device may be one that can have issues, something like this :

//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
     }
}

So this was the simplest part, to detect if the running device may have issues in streaming the video. Now, what I did and may also help you, is buffer the video from Youtube in a file on the SDCard and set that file as the source for your VideoView. I will write some code snippets to see how my approach was :

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

Another issue will arise when the VideoView has stopped playing before the end of file, because not enough was buffered in the file. For this you need to set an onCompletionListener() and if you are not at the end of the video, you should start again the video playback from the last position :

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

}

In the end, of course the GetYoutubeFile thread is started in the onCreate() method :

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    //init views,player,etc
    new GetYoutubeFile().start();
}

Some modifications and adaptation I think will have to be done for this code, and it may not be the best approach, but it helped me, and I couldn't find any alternative.

这篇关于流至VideoView只能使用三星手机的时候扮演的无线上网的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆