Android: MediaPlayer безразличный или бесшовный просмотр видео

Я могу воспроизводить видео очень хорошо, реализуя OnCompletionListener, чтобы установить источник данных в другой файл. Проблем нет. Я вызываю reset () и готовлю () просто отлично.

То, что я не смог понять, заключается в том, как избавиться от мерцания на 1-2 секунды между изменением источника данных и запуском нового видео. Зазор показывает черный экран, и я не нашел способа обойти его.

Я попытался установить фон родительского представления на изображение, но ему удается обойти это. Даже если SurfaceView прозрачен (по умолчанию он по умолчанию.) Я также пытался одновременно воспроизводить несколько видеофайлов и переключать отображение медиаплеера, когда он заканчивается, а другой должен начинаться.

Последнее, что я пробовал, состояло в том, чтобы иметь второе представление в фоновом режиме, которое я показываю временно, пока видео «готовит» и удаляет его, когда видео готово к запуску. Это также было не очень бесшовно.

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

main.xml

<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:background="@drawable/background" android:layout_height="fill_parent"> <SurfaceView android:id="@+id/surface" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_gravity="center"> </SurfaceView> </FrameLayout> 

Player.java

 public class Player extends Activity implements OnCompletionListener, MediaPlayer.OnPreparedListener, SurfaceHolder.Callback { private MediaPlayer player; private SurfaceView surface; private SurfaceHolder holder; public void onCreate(Bundle b) { super.onCreate(b); setContentView(R.layout.main); surface = (SurfaceView)findViewById(R.id.surface); holder = surface.getHolder(); holder.addCallback(this); holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); } public void onCompletion(MediaPlayer arg0) { File clip = new File(Environment.getExternalStorageDirectory(),"file2.mp4"); playVideo(clip.getAbsolutePath()); } public void onPrepared(MediaPlayer mediaplayer) { holder.setFixedSize(player.getVideoWidth(), player.getVideoHeight()); player.start(); } private void playVideo(String url) { try { File clip = new File(Environment.getExternalStorageDirectory(),"file1.mp4"); if (player == null) { player = new MediaPlayer(); player.setScreenOnWhilePlaying(true); } else { player.stop(); player.reset(); } player.setDataSource(url); player.setDisplay(holder); player.setOnPreparedListener(this); player.prepare(); player.setOnCompletionListener(this); } catch (Throwable t) { Log.e("ERROR", "Exception Error", t); } } 

У меня тоже такая же проблема, как указано ниже ссылкой

VideoView исчезает в течение секунды при изменении видео

Но эта проблема не возникнет, если вы попытаетесь использовать Android 4.0+ (ICS). Я начал переносить VideoView.java и MediaPlayer.java с 4.0 на мое приложение, но это кажется сложным и не повезло до сих пор. В основном это кажется ошибкой в ​​собственном коде старых версий.

После слишком много потраченного впустую времени, пытаясь понять, как играть в последовательные видео без «пробела», я склоняюсь к невозможности. Если, конечно, вы не сможете выкопать на родной уровень и реализовать собственный плеер, мультимедийный проигрыватель Android просто не поддерживает плавное воспроизведение на данный момент.

Я не делал этого с воспроизведением видео на MediaPlayer, но я сделал что-то подобное с аудиофайлами, когда поток прерывается, потому что пользователь переключился с 3G на Wi-Fi.

Я думаю, что задержка, которую вы видите, пока медиаплеер буферизует входной файл. Может быть, вы можете определить обоих игроков в начале? Вы должны определить источник данных и подготовить обоих игроков, но только запустить один из них.

Затем в вашем onCompletionListener вы можете перевернуть их вместо сброса существующего и установки нового источника данных.

  player.release(); player = flipPlayer; flipPlayer = null; player.start(); 

Очевидно, вам нужно либо использовать другой onPreparedListener для flipPlayer, либо взять player.start () из onPrepare. (Поскольку вы называете это синхронно, я бы не подумал, что это проблема).

Я не думаю, что это возможно.

Причина: Mortplayer также был доступен для Windows Mobile, и одна из его сильных сторон заключалась в том, что он поддерживал беспроблемную игру. Однако это не в версии Android для приложения, и сам разработчик пишет, что SDK не разрешает его на xda: http://forum.xda-developers.com/showpost.php?p=5364530&postcount=5

HTH, Даниэле

Вы пытались подготовить (открыли / подготовили) 2 VideoView, один из которых был видимым, другим невидимым и остановился, и задница скоро вы получите обратный вызов OnCompletionListener, сделайте второй видимым, запустите его и скройте 1-й. Тем временем, когда вы играете 2-го, вы можете открыть / подготовить 1-й видеообзор, чтобы открыть / подготовить другой файл.

@ User1263019 – вы могли переносить Android 4.0 MediaPlayer в свое приложение? Я сталкиваюсь с той же проблемой, и я ищу хорошее решение. У моего случая есть изображение поверх SurfaceView, которое должно быть скрыто, чтобы показать воспроизведение видео, но есть разрыв между вызовом start () и фактическим началом видео. Единственное решение до сих пор – запустить Thread, который проверяет, есть ли getCurrentPosition ()> 0.

По теме – я думаю, что невозможно беззаботное воспроизведение, хотя Winamp претендует на такие способности. Грязная ручка состоит в том, чтобы подготовить второго игрока за несколько секунд до окончания воспроизведения первого игрока, а затем вызвать начало () второго игрока на 100-200 мс до окончания воспроизведения.

В вашей реализации exoplayer (или медиаплеер) используйте обработчик для повторной отправки runnable во время игры, который получает текущее время отслеживания и передает его на обратный вызов:

 public interface MediaAction { public void onTrackingChanged(long currentPosition); } public class ExoPlayerImplementation implements Exoplayer { .. private MediaAction mediaActionCallback; public void setMediaActionCallback(MediaAction ma) { mediaActionCallback = ma; } public void releaseMediaAction() { mediaActionCallback = null; } private Handler trackingCallback = new Handler(Looper.getMainLooper()); Runnable trackingTask; private Runnable getTrackingTask() { Runnable r = new Runnable { @Override public void run() { long currentPosition = getCurrentPosition(); if (mediaActionCallback != null) { mediaActionCallback.onTrackingChanged(currentPosition); } // 60hz is 16 ms frame delay... trackingCallback.postDelayed(getTrackingTask(), 15); } }; trackingTask = r; return r; } public void play() { // exoplayer start code trackingCallback.post(getTrackingTask()); } public void pause/stop() { trackingCallback.removeCallbacks(trackingTask); } .. } 

И теперь вы можете отслеживать, когда текущая позиция на самом деле изменилась – если она изменилась, вы можете показать свои видеовыходы / просмотреть swap / удалить предварительный просмотр (т. Е. Использовать MediaExtractor для захвата исходных кадров, наложить как предварительный просмотр в ImageView, затем Скрыть, как только текущее положение увеличивается). Вы можете сделать этот код более полным, объединив его с прослушивателем состояния: тогда вы знаете, буферизуете ли вы (проверяете положение буферизации против текущей позиции), фактически играете, приостанавливаете или останавливаете с помощью соответствующих обратных вызовов (в MediaAction). Вы можете применить этот метод к классам MediaPlayer и ExoPlayer (поскольку это просто интерфейс и обработчик).

Надеюсь, это поможет!

Intereting Posts
Кнопки с радиоприемниками Установите проверочное состояние с помощью кода Windows 7 64-битная ошибка запуска AVD AVD: не удалось выделить память: 8 Android Studio не взаимодействует с adb GLIBC … не найдена ошибка Проблемы с Android с eclipse Использование Android AutoCompleteTextView с ArrayAdapter <Objects> вместо ArrayAdapter <Strings> Нечеткие точки утечки памяти Android не ясны! Как оптимизировать «имя класса» в макете Android XML? Как сделать мигание / мигание экрана из фоновой службы на устройстве Android? Android MVP open Activity from Presenter, анти-шаблон? Невозможно разрешить хост «<insert URL here>» Нет адреса, связанного с именем хоста Можно ли использовать Butterknife для инъекций представлений в espresso Test clases в android? Как зарегистрировать мой собственный подкласс приложения в Xamarin.Android? Можно ли хранить ссылки на фрагмент в AsyncTask? Можно ли получить контактную информацию «Владелец» в Android? «В вашем контенте должен быть ListView, атрибут id которого является« android.R.id.list ». При смене ListActivity на представление