Cómo reproducir múltiples archivos de video simultáneamente en un diseño uno al lado del otro en diferentes vistas en Android

En Android, creé un diseño con tres vistas de superficies una al lado de la otra, y quiero reproducir un archivo de video con diferentes reproductores multimedia simultáneamente. Pero un problema que enfrenté es que ninguno de los tres puede reproducir ese video simultáneamente. Uno o dos de ellos pararon la pantalla. Si utilicé la vista de video en lugar de la clase Media Player directamente, el problema sigue siendo el mismo. Por favor, cualquiera puede ayudar. ¿Para qué es el problema? Está dando un error nativo fallido de creación de superficie. Probé una combinación diferente, como un archivo en 3 vistas diferentes, tres archivos en tres vistas diferentes, pero el problema aún no está solucionado. Algunas respuestas en otro sitio web dicen que depende de la versión del kernel. Si depende de la versión de Kernel, puede darme cualquier enlace de documentación de Android en el sitio de Android que dependa de la versión del kernel. O es posible jugar, por favor dame los pasos del código. Este es un registro de error –

04-10 19:23:37.995: E/ANDROID_DRM_TEST(2573): Client::notify In 04-10 19:23:37.995: V/AudioPolicyManager(2573): startOutput() output 1, stream 3, session 131 04-10 19:23:37.995: V/AudioPolicyManager(2573): getDeviceForStrategy() from cache strategy 0, device 2 04-10 19:23:37.995: V/AudioPolicyManager(2573): getNewDevice() selected device 2 04-10 19:23:37.995: V/AudioPolicyManager(2573): setOutputDevice() output 1 device 2 delayMs 0 04-10 19:23:37.995: V/AudioPolicyManager(2573): setOutputDevice() setting same device 2 or null device for output 1 04-10 19:23:37.995: I/AudioFlinger(2573): start output streamType (0, 3) for 1 04-10 19:23:37.995: D/AudioHardwareYamaha(2573): AudioStreamOut::setParameters(keyValuePairs="start_output_streamtype=3") 04-10 19:23:38.010: W/SEC_Overlay(2689): overlay_setPosition(0) 0,0,200,397 => 0,0,200,397 04-10 19:23:38.010: I/SEC_Overlay(2689): overlay_setParameter param[4]=4 04-10 19:23:38.010: D/SEC_Overlay(2689): dst width, height have changed [w= 200, h= 397] -> [w=200, h= 397] 04-10 19:23:38.010: I/SEC_Overlay(2689): Nothing to do! 04-10 19:23:38.090: E/VideoMIO(2573): AndroidSurfaceOutput::setParametersSync() VIDEO ROTATION 0 04-10 19:23:38.090: E/VideoMIO(2573): AndroidSurfaceOutput::setParametersSync() VIDEO RENDERER 1 04-10 19:23:38.090: D/SEC_Overlay(2689): overlay_createOverlay:IN w=128 h=96 format=48 04-10 19:23:38.090: E/SEC_Overlay(2689): Error - overlays already in use 04-10 19:23:38.090: D/VideoMIO(2573): Overlay create failed - retrying 04-10 19:23:38.195: D/SEC_Overlay(2689): overlay_createOverlay:IN w=128 h=96 format=48 04-10 19:23:38.195: E/SEC_Overlay(2689): Error - overlays already in use 04-10 19:23:38.195: D/VideoMIO(2573): Overlay create failed - retrying 04-10 19:23:38.230: E/VideoMIO(2573): AndroidSurfaceOutput::setParametersSync() VIDEO ROTATION 0 04-10 19:23:38.230: E/VideoMIO(2573): AndroidSurfaceOutput::setParametersSync() VIDEO RENDERER 1 04-10 19:23:38.230: D/SEC_Overlay(2689): overlay_createOverlay:IN w=128 h=96 format=48 04-10 19:23:38.230: E/SEC_Overlay(2689): Error - overlays already in use 04-10 19:23:38.230: D/VideoMIO(2573): Overlay create failed - retrying 04-10 19:23:38.295: D/SEC_Overlay(2689): overlay_createOverlay:IN w=128 h=96 format=48 04-10 19:23:38.295: E/SEC_Overlay(2689): Error - overlays already in use 04-10 19:23:38.295: D/VideoMIO(2573): Overlay create failed - retrying 04-10 19:23:38.330: D/SEC_Overlay(2689): overlay_createOverlay:IN w=128 h=96 format=48 04-10 19:23:38.330: E/SEC_Overlay(2689): Error - overlays already in use 04-10 19:23:38.330: D/VideoMIO(2573): Overlay create failed - retrying 04-10 19:23:38.395: D/SEC_Overlay(2689): overlay_createOverlay:IN w=128 h=96 format=48 04-10 19:23:38.395: E/SEC_Overlay(2689): Error - overlays already in use 04-10 19:23:38.395: D/VideoMIO(2573): Overlay create failed - retrying 04-10 19:23:38.435: D/SEC_Overlay(2689): overlay_createOverlay:IN w=128 h=96 format=48 04-10 19:23:38.435: E/SEC_Overlay(2689): Error - overlays already in use 04-10 19:23:38.435: D/VideoMIO(2573): Overlay create failed - retrying 04-10 19:23:38.495: D/SEC_Overlay(2689): overlay_createOverlay:IN w=128 h=96 format=48 04-10 19:23:38.495: E/SEC_Overlay(2689): Error - overlays already in use 04-10 19:23:38.495: D/VideoMIO(2573): Overlay create failed - retrying 04-10 19:23:38.535: D/SEC_Overlay(2689): overlay_createOverlay:IN w=128 h=96 format=48 

No está dando muchos detalles sobre qué es exactamente lo que ha intentado y cuáles son las áreas problemáticas, así que hice una pequeña prueba para ver si podía reproducir algo de lo que está describiendo.

No tengo ningún hallazgo concluyente, pero al menos puedo confirmar que mi Galaxy Nexus (Android 4.0.2) puede reproducir tres videos simultáneamente sin ningún problema. Por otro lado, un viejo Samsung Galaxy Spica (Android 2.1-update1) que tenía en el mercado solo reproduce un solo archivo a la vez, parece ser siempre el primer SurfaceView .

Investigué además diferentes niveles de API configurando emuladores para Android 3.0, 2.3.3 y 2.2. Parece que todas estas plataformas son capaces de manejar la reproducción de múltiples archivos de video en diferentes vistas de la superficie. Hice una prueba final con un emulador ejecutando 2.1-update1 también, que curiosamente también jugó el caso de prueba sin problemas, a diferencia del teléfono real. Sin embargo, noté algunas pequeñas diferencias en cómo se trazó el diseño.

Este comportamiento me lleva a sospechar que no existe realmente ninguna limitación de software para lo que está buscando, pero parece depender del hardware si se admite la reproducción simultánea de múltiples archivos de video. Por lo tanto, el soporte para este escenario variará según el dispositivo. Desde un punto de vista emperical, definitivamente creo que sería interesante probar esta hipótesis en algunos dispositivos más físicos.

Solo como referencia algunos detalles con respecto a la implementación:

  1. Configuré dos implementaciones ligeramente diferentes: una basada en tres instancias de MediaPlayer en una sola Activity , y una en la que se dividieron en tres fragmentos separados con cada uno su propio objeto MediaPlayer . (Por cierto, no encontré ninguna diferencia de reproducción para estas dos implementaciones)
  2. Se utilizó un único archivo de 3gp (gracias a eso, Apple), ubicado en la carpeta assets , para reproducir con todos los reproductores.
  3. El código para ambas implementaciones se adjunta a continuación y se basa principalmente en la implementación de la muestra Googles MediaPlayerDemo_Video eliminé un código que no era necesario para las pruebas reales. El resultado de ninguna manera es completo o adecuado para usar en aplicaciones en vivo.

Implementación basada en la actividad:

 public class MultipleVideoPlayActivity extends Activity implements OnBufferingUpdateListener, OnCompletionListener, OnPreparedListener, OnVideoSizeChangedListener, SurfaceHolder.Callback { private static final String TAG = "MediaPlayer"; private static final int[] SURFACE_RES_IDS = { R.id.video_1_surfaceview, R.id.video_2_surfaceview, R.id.video_3_surfaceview }; private MediaPlayer[] mMediaPlayers = new MediaPlayer[SURFACE_RES_IDS.length]; private SurfaceView[] mSurfaceViews = new SurfaceView[SURFACE_RES_IDS.length]; private SurfaceHolder[] mSurfaceHolders = new SurfaceHolder[SURFACE_RES_IDS.length]; private boolean[] mSizeKnown = new boolean[SURFACE_RES_IDS.length]; private boolean[] mVideoReady = new boolean[SURFACE_RES_IDS.length]; @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); setContentView(R.layout.multi_videos_layout); // create surface holders for (int i=0; i 

R.layout.multi_videos_layout:

       

Implementación basada en fragmentos:

 public class MultipleVideoPlayFragmentActivity extends FragmentActivity { private static final String TAG = "MediaPlayer"; @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); setContentView(R.layout.multi_videos_activity_layout); } public static class VideoFragment extends Fragment implements OnBufferingUpdateListener, OnCompletionListener, OnPreparedListener, OnVideoSizeChangedListener, SurfaceHolder.Callback { private MediaPlayer mMediaPlayer; private SurfaceView mSurfaceView; private SurfaceHolder mSurfaceHolder; private boolean mSizeKnown; private boolean mVideoReady; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { return inflater.inflate(R.layout.multi_videos_fragment_layout, container, false); } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); mSurfaceView = (SurfaceView) getView().findViewById(R.id.video_surfaceview); mSurfaceHolder = mSurfaceView.getHolder(); mSurfaceHolder.addCallback(this); mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); } public void onBufferingUpdate(MediaPlayer player, int percent) { Log.d(TAG, "onBufferingUpdate percent: " + percent); } public void onCompletion(MediaPlayer player) { Log.d(TAG, "onCompletion called"); } public void onVideoSizeChanged(MediaPlayer player, int width, int height) { Log.v(TAG, "onVideoSizeChanged called"); if (width == 0 || height == 0) { Log.e(TAG, "invalid video width(" + width + ") or height(" + height + ")"); return; } mSizeKnown = true; if (mVideoReady && mSizeKnown) { startVideoPlayback(); } } public void onPrepared(MediaPlayer player) { Log.d(TAG, "onPrepared called"); mVideoReady = true; if (mVideoReady && mSizeKnown) { startVideoPlayback(); } } public void surfaceChanged(SurfaceHolder holder, int i, int j, int k) { Log.d(TAG, "surfaceChanged called"); } public void surfaceDestroyed(SurfaceHolder holder) { Log.d(TAG, "surfaceDestroyed called"); } public void surfaceCreated(SurfaceHolder holder) { Log.d(TAG, "surfaceCreated called"); try { mMediaPlayer = new MediaPlayer(); AssetFileDescriptor afd = getActivity().getAssets().openFd("sample.3gp"); mMediaPlayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength()); mMediaPlayer.setDisplay(mSurfaceHolder); mMediaPlayer.prepare(); mMediaPlayer.setOnBufferingUpdateListener(this); mMediaPlayer.setOnCompletionListener(this); mMediaPlayer.setOnPreparedListener(this); mMediaPlayer.setOnVideoSizeChangedListener(this); mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); } catch (Exception e) { e.printStackTrace(); } } @Override public void onPause() { super.onPause(); releaseMediaPlayer(); } @Override public void onDestroy() { super.onDestroy(); releaseMediaPlayer(); } private void releaseMediaPlayer() { if (mMediaPlayer != null) { mMediaPlayer.release(); mMediaPlayer = null; } } private void startVideoPlayback() { Log.v(TAG, "startVideoPlayback"); mMediaPlayer.start(); } } } 

R.layout.multi_videos_activity_layout:

       

R.layout.multi_videos_fragment_layout:

   

Actualización: Aunque ha estado disponible por un tiempo, pensé que sería útil señalar que el proyecto Grafika de Google muestra una función de "doble deencoding" , que " decodifica dos transmisiones de video simultáneamente con dos TextureViews". No estoy seguro de qué tan bien se adapta a más de dos archivos de video, pero relevante para la pregunta original.

Saca este código, funciona …

 video1=(VideoView)findViewById(R.id.myvideoview); video1.setVideoURI(Uri.parse("android.resource://" +getPackageName()+ "/"+R.raw.sample)); video1.setMediaController(new MediaController(this)); video1.requestFocus(); video2=(VideoView)findViewById(R.id.myvideview); video2.setVideoURI(Uri.parse("android.resource://" +getPackageName()+ "/"+R.raw.sample1)); video2.setMediaController(new MediaController(this)); video2.requestFocus(); Thread view1=new Thread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_DISPLAY); video1.start(); } }); Thread view2=new Thread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_DISPLAY); video2.start(); } }); 

Pero depende de su dispositivo h / w si admite multi video-view o no. Si no lo admite, le dará error ya que This video can not be played Error (1, -110)

Encontré una solución. Simplemente reemplace /system/build.prop con este siguiente build.prop –

build.prop

 # begin build properties # autogenerated by buildinfo.sh ro.build.id=GINGERBREAD ro.build.display.id=GINGERBREAD.EG14 ro.build.version.incremental=EG14 ro.build.version.sdk=10 ro.build.version.codename=REL ro.build.version.release=2.3.4 ro.build.date=Thu Jul 14 12:16:01 KST 2011 ro.build.date.utc=1310613361 ro.build.type=user ro.build.user=se.infra ro.build.host=SEI-28 ro.build.tags=release-keys ro.product.model=SHW-M250S ro.product.brand=samsung ro.product.name=SHW-M250S ro.product.device=SHW-M250S ro.product.board=SHW-M250S ro.product.cpu.abi=armeabi-v7a # Samsung Specific Properties ro.build.PDA=M250S.EG14.1208 ro.build.hidden_ver=M250S.EG14.1208 ro.b uild.changelist=380592 ro.product.cpu.abi2=armeabi ro.product.manufacturer=samsung ro.product.locale.language=ko ro.product.locale.region=KR ro.wifi.channels= ro.board.platform=s5pc210 # ro.build.product is obsolete; use ro.product.device ro.build.product=SHW-M250S # Do not try to parse ro.build.description or .fingerprint ro.build.description=SHW-M250S-user 2.3.4 GINGERBREAD EG14 release-keys ro.build.fingerprint=samsung/SHW-M250S/SHW-M250S:2.3.4/GINGERBREAD/EG14:user/release-keys # Samsung Specific Properties ro.build.PDA=M250S.EG14.1208 ro.build.hidden_ver=M250S.EG14.1208 ro.build.changelist=380592 ro.build.fota_ver=SSNT11GINGEREG14 ro.tether.denied=false ro.flash.resolution=1080 # end build properties # # system.prop for asop5000 # rild.libpath=/system/lib/libsec-ril.so rild.libargs=-d /dev/ttyS0 ro.sf.lcd_density=240 dalvik.vm.heapsize=64m # Samsung USB default mode persist.service.usb.setting=2 # # ADDITIONAL_BUILD_PROPERTIES # ro.setupwizard.mode=OPTIONAL ro.com.google.gmsversion=2.3_r4 media.stagefright.enable-player=true media.stagefright.enable-meta=true media.stagefright.enable-scan=true media.stagefright.enable-http=true media.stagefright.enable-rtsp=true ro.com.google.clientidbase=android-samsung ro.com.google.clientidbase.ms=android-skt-kr ro.com.google.clientidbase.am=android-skt-kr ro.com.google.clientidbase.gmm=android-samsung ro.com.google.clientidbase.yt=android-samsung ro.url.legal=http://www.google.com/intl/%s/mobile/android/basic/phone-legal.html ro.url.legal.android_privacy=http://www.google.com/intl/%s/mobile/android/basic/privacy.html ro.com.google.locationfeatures=1 keyguard.no_require_sim=true ro.config.ringtone=Over_the_horizon.ogg ro.config.notification_sound=Sherbet.ogg ro.config.alarm_alert=Good_Morning.ogg ro.config.media_sound=Over_the_horizon.ogg ro.opengles.version=131072 ro.csc.sales_code=MSK ro.secdevenc=true ro.wtldatapassword=true net.bt.name=Android dalvik.vm.stack-trace-file=/data/anr/traces.txt 

Al principio, conecta tu Samsung Galaxy s-II con usb y escribe el símbolo del sistema para montar tu sistema:

 cmd:> adb remount 

y luego reemplace el archivo y reinicie su dispositivo –

 cmd:> adb shell #reboot 

Me he dado cuenta de que, de forma predeterminada, este dispositivo usa Opencore Framework en lugar de libstagefright. Y Opencore tiene algún problema, es por eso que el error de la nave es arrojar. Pero libstagefright ya está implementado en la versión 2.3 de Android. Echa un vistazo al archivo build.prop, el stagefright está deshabilitado. Es la mejor solución para habilitar el framework libstagefright y admite el framework libstagefright. También puede reproducir archivos MPEG-2TS y es compatible para reproducir múltiples archivos de video simultáneamente sin tener ningún problema. Pruébalo y disfruta.

No estás dando ningún ejemplo de código.

Según mi experiencia, he descubierto que puedes hacer esto con Fragments (al menos en los dispositivos que he usado). Recuerde que hay una biblioteca de soporte Fragment para dispositivos más antiguos.

Así que básicamente coloque un LinearLayout o algo en lugar de las VideoViews, luego use las transacciones de Fragment para reemplazar LinearLayouts con un Fragment que tenga una VideoView.

Prueba esto

 public class CustomPictureActivity extends Activity { /** Called when the activity is first created. */ VideoView vd1,vd2; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); vd1=(VideoView) findViewById(R.id.v1); vd2=(VideoView) findViewById(R.id.v2); vd1.setVideoURI(Uri.parse("/mnt/sdcard/file.mp4")); vd1.setMediaController(new MediaController(this)); vd1.requestFocus(); vd1.start(); vd2.setVideoURI(Uri.parse("/mnt/sdcard/android.mp4")); vd2.setMediaController(new MediaController(this)); vd2.requestFocus(); vd2.start(); } 

}

y xml debería ser así