Потоковая передача в VideoView воспроизводится только через Wi-Fi при использовании телефонов Samsung.

Я использую следующую библиотеку для потоковой передачи видео с YouTube в приложение для Android.

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

Я успешно могу воспроизводить видео на телефонах HTC и Motorola через 3G и Wi-Fi. Однако на телефонах Samsung Galaxy (Epic 4G) и Samsung Galaxy II я могу играть только через Wi-Fi. 3G выдает мне эту ошибку: «Невозможно воспроизвести видео. Извините, это видео невозможно воспроизвести».

Я пробовал форсировать низкокачественную потоковую передачу на YouTube, но это не помогло. Я вижу в своем журнале, что Start() вызывается в обоих случаях (3G/Wifi). Это проблема с VideoView? Есть ли обходной путь?

Изменить 2

Видео поступают из YouTube API. Я пытался использовать встроенные и обычные потоки, а также доступный поток самого низкого качества (в зависимости от видео). Кроме того, я не думаю, что это проблема с кодировкой, поскольку одни и те же видео воспроизводятся правильно с использованием Wi-Fi.

Изменить 1

Я также получаю следующий вывод независимо от того, воспроизводится ли видео с использованием Wi-Fi или без использования 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;
/*

Дальнейшее добавление путаницы.


person Oh Danny Boy    schedule 30.01.2012    source источник
comment
похоже, что эта проблема затрагивает другие устройства.   -  person Zakaria    schedule 31.01.2012
comment
@ Закария Ах, да. Спасибо, что указали на это.   -  person Oh Danny Boy    schedule 31.01.2012
comment
Можете ли вы также сообщить нам, каковы уровни API ваших устройств? Что работает и что не работает.   -  person Ovidiu Latcu    schedule 15.02.2012
comment
Пробовали ли вы воспроизводить видео через 3G с помощью веб-браузера по умолчанию на телефоне Samsung, работает ли он правильно?   -  person yorkw    schedule 15.02.2012


Ответы (3)


Да, как вы думаете, это проблема в VideoView, подобные проблемы возникают и в MediaPlayer, и я сталкивался с такими же и странными проблемами, как и вы, у меня были проблемы, когда видео воспроизводилось только на 3G, а не на Wi- Фи. Обычно это происходит на устройствах 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 для вашего 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():

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

Некоторые модификации и адаптации, я думаю, придется сделать для этого кода, и это может быть не лучший подход, но мне он помог, и я не смог найти никакой альтернативы.

person Ovidiu Latcu    schedule 15.02.2012
comment
не проверял, но определенно +1 к логике! Я только что просмотрел этот код YouTubePlayer и заметил некоторые проверки для WIFI. Это вызовет проблему? Я имею в виду, вы уверены, что это проблема VideoView? - person Sherif elKhatib; 15.02.2012
comment
Не могу сказать, что уверен на 100%. Но я точно знаю, что одно и то же видео работало по 3G, а не по WiFi на некоторых устройствах, и наоборот на некоторых других устройствах. Так что я могу только думать, что это что-то внутри VideoView, а не проблема с форматом видео. - person Ovidiu Latcu; 15.02.2012

Я решаю эту проблему по-своему. Сначала каждый раз читайте свой лог.

Error (1,-1) 

это означает, что вы получите sorry,this video can not play message. Итак, в этом случае завершите это действие, задайте пользовательский индикатор выполнения и загрузите видео. Затем после загрузки сохраните его во временной папке, а затем воспроизведите. После воспроизведения удалите эту папку.

Для чтения журнала 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, будет говорить "Извините, это видео не может быть воспроизведено". Однажды я так разозлился на это, что просто продолжал нажимать «ОК», чтобы закрыть сообщение, а затем снова нажимал видео только для того, чтобы снова увидеть сообщение «Извините, это видео не может быть воспроизведено». Я повторил этот процесс (в своем слепом гневе), но в конце концов, примерно после 5 попыток, видео решило чудесным образом воспроизвести!

Этот метод почти всегда работает для меня. Большинство видео не хотят воспроизводиться в первый раз, но в конце концов, если я просто буду настойчив и буду продолжать говорить ему, чтобы оно воспроизводилось, даже если оно говорит мне, что «не может» воспроизвести видео, оно будет воспроизводиться! Хотя для некоторых видео мне приходилось нажимать «ОК», нажимать видео, нажимать «ОК», нажимать видео и т. д. примерно 20 раз, прежде чем оно действительно решило воспроизвести. В те времена я был невероятно близок к тому, чтобы взять свой телефон и бросить его на пол из-за того, насколько я дерьмовый из-за того, что YouTube не работает.

Хотелось бы, чтобы был способ решить эту проблему. Кажется, никто не придумал решения. Все просто говорят: «О да, у меня такая же проблема», но никто ничего не делает. GOOGLE, РЕШИТЕ ​​ЭТУ ПРОБЛЕМУ НА ВАШИХ ТЕЛЕФОНАХ. ЭТО ПРОИСХОДИТ ПО ВСЕМУ МИРУ, НА РАЗНОМ ТЕЛЕФОНЕ ANDROID.

person Tofeeq Ahmad    schedule 16.02.2012
comment
Вас устраивает мой ответ? - person Tofeeq Ahmad; 16.02.2012
comment
Вам не нужно читать logcat, вы можете прикрепить метод обратного вызова onErrorListner, который даст вам эту ошибку - person Yahya Arshad; 03.07.2012
comment
Вы также можете сделать это.. но иногда это не входит в onErrorListner - person Tofeeq Ahmad; 04.07.2012
comment
Спасибо, тот же, за вашу информацию, я планировал использовать список onError для своего приложения, но вы меня обновили :) - person Yahya Arshad; 06.07.2012
comment
пожалуйста, скажите мне, есть ли какой-либо метод обратного вызова для чтения журнала, или я должен опросить ваш алгоритм в потоке - person Yahya Arshad; 06.07.2012
comment
@Cheeta: вы можете установить прослушиватель onError, если у вас возникла ошибка, а затем прочитать logcat - person Tofeeq Ahmad; 06.07.2012

Это сообщение часто появляется из-за неправильной кодировки видео («Невозможно воспроизвести видео. Извините, это видео невозможно воспроизвести».) Какое-то время я боролся с просмотром видео, теперь правильно закодированные видео воспроизводятся на всех протестированных устройствах, даже при использовании Wi-Fi. или 3G. Дайте им знать, если вы хотите знать, как кодировать видео. А для потоковой передачи видео я использовал демоверсию Android SDK APIs, и она работает безупречно.

person Iulia Barbu    schedule 07.02.2012
comment
Если это так, то почему одни и те же видео работают по вайфаю? - person Oh Danny Boy; 07.02.2012