2011-04-06 29 views
9

he implementado RTSP en Android usando VLC Media Player como RTSP servidor con este código:RTP en Android MediaPlayer

# vlc -vvv /home/marco/Videos/pippo.mp4 --sout 
#rtp{dst=192.168.100.246,port=6024-6025,sdp=rtsp://192.168.100.243:8080/test.sdp} 

y en el proyecto Android:


Uri videoUri = Uri.parse("rtsp://192.168.100.242:8080/test.sdp"); 
videoView.setVideoURI(videoUri); 
videoView.start(); 

Esto funciona bien, pero si también quisiera reproducir RTP en tiempo real, entonces copié el archivo sdp en la tarjeta sd (/mnt/sdcard/test.sdp) y el establecimiento de VLC:

# vlc -vvv /home/marco/Videos/pippo.mp4 --sout 
#rtp{dst=192.168.100.249,port=6024-6025} 

me trató de jugar el establecimiento de la ruta del archivo SDP localmente el flujo RTP:


Uri videoUri = Uri.parse("/mnt/sdcard/test.sdp"); 
videoView.setVideoURI(videoUri); 
videoView.start(); 

Pero tengo un error:


D/MediaPlayer(9616): Couldn't open file on client side, trying server side 
W/MediaPlayer(9616): info/warning (1, 26) 
I/MediaPlayer(9616): Info (1,26) 
E/PlayerDriver( 76): Command PLAYER_INIT completed with an error or info PVMFFailure 
E/MediaPlayer(9616): error (1, -1) 
E/MediaPlayer(9616): Error (1,-1) 
D/VideoView(9616): Error: 1,-1 

¿Alguien sabe cuál es el problema? ¿Estoy equivocado o no es posible jugar RTP en MediaPlayer? Cheers Giorgio

Respuesta

-1

Desafortunadamente no es posible reproducir un RTP Stream con el MediaPlayer de Android.

Las soluciones a este problema incluyen la decodificación de la secuencia RTP con ffmpeg. Se pueden encontrar tutoriales sobre cómo compilar ffmpeg para Android en la Web.

+0

¿Nos puede mostrar algunos ¿campo de golf? –

+1

Busqué mucho en Internet y hay varios tutoriales y publicaciones que explican cómo construirlo. Algunos trabajan y otros no. Es posible que desee echar un vistazo a esta publicación http://www.roman10.net/?p=389 o incluso ver lo que hizo la gente de RockPlayer http://www.rockplayer.com/tech_en.html. La primera descripción se basa en el script creado por los chicos de RockPlayer. – ladi

2

Tengo una solución parcial para usted.

Actualmente estoy trabajando en un proyecto Ra & D que implica la transmisión RTP de medios de un servidor a clientes de Android.

Al hacer este trabajo, contribuyo a mi propia biblioteca llamada smpte2022lib que puede encontrar aquí: http://sourceforge.net/projects/smpte-2022lib/.

Ayudado con tal biblioteca (la implementación Java es actualmente el mejor) que puede ser capaz de analizar las secuencias de multidifusión RTP procedentes de equipamientos de transmisión profesional, sesiones RTP VLC, ...

ya probado con éxito con flujos provenientes de streamings RTP profesionnales capturados con SMPTE-2022 2D-FEC o con streams simples generados con VLC.

Lamentablemente no puedo poner un fragmento de código aquí, ya que el proyecto que lo usa está en realidad bajo copyright, pero me aseguro de que puede usarlo simplemente mediante el análisis de secuencias UDP ayudadas con el constructor de RtpPacket.

Si los paquetes son paquetes RTP válidos (los bytes) se decodificarán como tales.

En este momento, envuelvo la llamada al constructor de RtpPacket en un hilo que realmente almacena la carga decodificada como un archivo multimedia.Luego llamaré a VideoView con este archivo como parámetro.

dedos de la travesía ;-)

Saludos cordiales,

David Fischer

0

Posible en Android usando (no MediaPlayer pero otras cosas más abajo en la pila), pero lo que realmente quiere no perseguir RTSP/RTP cuando el resto del ecosistema de medios no?

IMO: hay muchos mejores enfoques de medios/transmisión bajo el paraguas de HTML5/WebRTC. Observe lo que 'Ondello' está haciendo con las transmisiones.

Dicho esto, aquí hay un código de proyecto anterior para android/RTSP/SDP/RTP usando 'netty' y 'eflujo'. Negociará algunas partes de 'Sesiones' en proveedores de archivos SDP. No puedo recordar si realmente reproduciría la parte de audio de Youtube/RTSP stuff, pero ese era mi objetivo en ese momento. (Creo que funcionaba utilizando el códec AMR-NB, pero había un montón de problemas y se me cayó RTSP en android como un mal hábito!)

on Git ....

 @Override 
     public void mediaDescriptor(Client client, String descriptor) 
     { 
      // searches for control: session and media arguments. 
      final String target = "control:"; 
      Log.d(TAG, "Session Descriptor\n" + descriptor); 
      int position = -1; 
      while((position = descriptor.indexOf(target)) > -1) 
      { 
       descriptor = descriptor.substring(position + target.length()); 
       resourceList.add(descriptor.substring(0, descriptor.indexOf('\r'))); 
      } 
     } 
     private int nextPort() 
     { 
      return (port += 2) - 2; 
     }  


     private void getRTPStream(TransportHeader transport){ 

      String[] words; 
      // only want 2000 part of 'client_port=2000-2001' in the Transport header in the response 

      words = transport.getParameter("client_port").substring(transport.getParameter("client_port").indexOf("=") +1).split("-"); 
      port_lc = Integer.parseInt(words[0]); 

      words = transport.getParameter("server_port").substring(transport.getParameter("server_port").indexOf("=") +1).split("-"); 
      port_rm = Integer.parseInt(words[0]); 

      source = transport.getParameter("source").substring(transport.getParameter("source").indexOf("=") +1);   
      ssrc = transport.getParameter("ssrc").substring(transport.getParameter("ssrc").indexOf("=") +1); 
      // assume dynamic Packet type = RTP , 99 
      getRTPStream(session, source, port_lc, port_rm, 99); 
      //getRTPStream("sessiona", source, port_lc, port_rm, 99); 
      Log.d(TAG, "raw parms " +port_lc +" " +port_rm +" " +source); 
//   String[] words = session.split(";"); 
     Log.d(TAG, "session: " +session); 
     Log.d(TAG, "transport: " +transport.getParameter("client_port") 
       +" " +transport.getParameter("server_port") +" " +transport.getParameter("source") 
       +" " +transport.getParameter("ssrc")); 

     } 

     private void getRTPStream(String session, String source, int portl, int portr, int payloadFormat){ 
      // what do u do with ssrc? 
      InetAddress addr; 
      try { 
       addr = InetAddress.getLocalHost(); 
       // Get IP Address 
//    LAN_IP_ADDR = addr.getHostAddress(); 
       LAN_IP_ADDR = "192.168.1.125"; 
       Log.d(TAG, "using client IP addr " +LAN_IP_ADDR); 

      } catch (UnknownHostException e1) { 
       // TODO Auto-generated catch block 
       e1.printStackTrace(); 
      } 


      final CountDownLatch latch = new CountDownLatch(2); 

      RtpParticipant local1 = RtpParticipant.createReceiver(new RtpParticipantInfo(1), LAN_IP_ADDR, portl, portl+=1); 
    //  RtpParticipant local1 = RtpParticipant.createReceiver(new RtpParticipantInfo(1), "127.0.0.1", portl, portl+=1); 
      RtpParticipant remote1 = RtpParticipant.createReceiver(new RtpParticipantInfo(2), source, portr, portr+=1); 


      remote1.getInfo().setSsrc(Long.parseLong(ssrc, 16)); 
      session1 = new SingleParticipantSession(session, payloadFormat, local1, remote1); 

      Log.d(TAG, "remote ssrc " +session1.getRemoteParticipant().getInfo().getSsrc()); 

      session1.init(); 

      session1.addDataListener(new RtpSessionDataListener() { 
       @Override 
       public void dataPacketReceived(RtpSession session, RtpParticipantInfo participant, DataPacket packet) { 
    //    System.err.println("Session 1 received packet: " + packet + "(session: " + session.getId() + ")"); 
        //TODO close the file, flush the buffer 
//     if (_sink != null) _sink.getPackByte(packet); 
        getPackByte(packet); 

    //    System.err.println("Ssn 1 packet seqn: typ: datasz " +packet.getSequenceNumber() + " " +packet.getPayloadType() +" " +packet.getDataSize()); 
    //    System.err.println("Ssn 1 packet sessn: typ: datasz " + session.getId() + " " +packet.getPayloadType() +" " +packet.getDataSize()); 
//     latch.countDown(); 
       } 

      }); 
    //  DataPacket packet = new DataPacket(); 
     //  packet.setData(new byte[]{0x45, 0x45, 0x45, 0x45}); 
    //  packet.setSequenceNumber(1); 
    //  session1.sendDataPacket(packet); 


//  try { 
     //  latch.await(2000, TimeUnit.MILLISECONDS); 
    //  } catch (Exception e) { 
    //   fail("Exception caught: " + e.getClass().getSimpleName() + " - " + e.getMessage()); 

//  } 
     } 
//TODO below should collaborate with the audioTrack object and should write to the AT buffr 
     // audioTrack write was blocking forever 

    public void getPackByte(DataPacket packet) { 
      //TODO this is getting called but not sure why only one time 
      // or whether it is stalling in mid-exec?? 

      //TODO on firstPacket write bytes and start audioTrack 
      // AMR-nb frames at 12.2 KB or format type 7 frames are handled . 
      // after the normal header, the getDataArray contains extra 10 bytes of dynamic header that are bypassed by 'limit' 


      // real value for the frame separator comes in the input stream at position 1 in the data array 
      // returned by 

//   int newFrameSep = 0x3c; 
      // bytes avail = packet.getDataSize() - limit; 

//   byte[] lbuf = new byte[packet.getDataSize()]; 
//   if (packet.getDataSize() > 0) 
//    lbuf = packet.getDataAsArray(); 
      //first frame includes the 1 byte frame header whose value should be used 
      // to write subsequent frame separators 
      Log.d(TAG, "getPackByt start and play"); 

      if(!started){ 
       Log.d(TAG, " PLAY audioTrak"); 
       track.play(); 
       started = true; 
      } 

//   track.write(packet.getDataAsArray(), limit, (packet.getDataSize() - limit)); 
      track.write(packet.getDataAsArray(), 0, packet.getDataSize()); 
      Log.d(TAG, "getPackByt aft write"); 

//   if(!started && nBytesRead > minBufferSize){ 
    //   Log.d(TAG, " PLAY audioTrak"); 
     //  track.play(); 
     // started = true;} 
      nBytesRead += packet.getDataSize(); 
      if (nBytesRead % 500 < 375) Log.d(TAG, " getPackByte plus 5K received"); 
     }  
    } 
Cuestiones relacionadas