Intereting Posts
Проблема обновления Android SDK Tools rev 19 до версии 20 с использованием окон 7- 64 бит Почему маржа LinearLayout игнорируется при использовании в виде списка ListView Можно ли получить координаты в реальном времени ImageView, когда он находится в анимации трансляции? Изменение цвета курсора в SearchView без ActionBarSherlock Новый список приложений в стиле «Входящие» для Android с прорисовкой влево и вправо Зачем использовать фрагменты? Как EditText сохраняет свое значение, но не textview, когда меняется ориентация телефона? Android: отключить мягкую клавиатуру на всех EditTexts Как использовать команду adb pull? Как получить доступ к Wi-Fi-сетям и отобразить их в списке в Android Crosswalk Cordova – js alert показывает символы блока на китайском интерфейсе android Лучший способ использования ускорителя эмуляции Android x86 HAXM в Windows 8 с Hyperv Запуск Android Lint встретил … Сбой. java.lang.NullPointerException Откройте приложение Android из URL-адреса, не используя рабочий фильтр Как сделать приложение полноэкранным в Galaxy Tab

RTP на Android MediaPlayer

Я реализовал RTSP на Android MediaPlayer, используя VLC как сервер rtsp с этим кодом:

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

И в проекте Android:


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

Это прекрасно работает, но если я также хочу сыграть в режиме реального времени RTP, я скопировал файл sdp в sdcard (/mnt/sdcard/test.sdp) и установил vlc:

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

Я попытался воспроизвести поток RTP, устанавливающий путь к файлу sdp локально:


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

Но у меня есть ошибка:


 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 

Кто-нибудь знает, где проблема? Я ошибаюсь, или невозможно воспроизвести RTP на MediaPlayer? Cheers Giorgio

Solutions Collecting From Web of "RTP на Android MediaPlayer"

У меня есть частичное решение для вас.

В настоящее время я работаю над проектом Ra & D, включающим потоки RTP медиа с сервера на Android-клиентов.

Выполняя эту работу, я вношу свой вклад в свою собственную библиотеку под названием smpte2022lib, которую вы можете найти здесь: http://sourceforge.net/projects/smpte-2022lib/ .

Помог с такой библиотекой (в настоящее время реализация Java является лучшей), вы можете анализировать многоадресные потоки RTP, поступающие из профессиональных потоковых устройств, VLC RTP-сессий, …

Я уже успешно протестировал его с потоками, поступающими из захваченных профильных потоков RTP с помощью SMPTE-2022 2D-FEC или с помощью простых потоков, генерируемых VLC.

К сожалению, я не могу поместить здесь фрагмент кода, поскольку проект, использующий его, фактически находится под авторским правом, но я гарантирую, что вы можете использовать его просто, анализируя потоки UDP, связанные с конструктором RtpPacket.

Если пакеты действительны RTP-пакеты (байты), они будут декодированы как таковые.

В этот момент времени я завершу вызов конструктора RtpPacket в поток, который фактически хранит декодированную полезную нагрузку в качестве медиафайла. Затем я вызову VideoView с этим файлом в качестве параметра.

Пересечение пальцев 😉

С уважением,

Дэвид Фишер

Возможно, в android, используя (а не mediaPlayer, но другие вещи дальше по стеку), но вы действительно хотите, чтобы преследовать RTSP / RTP, когда остальная медиасистема не работает?

ИМО – есть намного лучшие медиа / потоковые подходы под эгидой HTML5 / WebRTC. Например, посмотрите, что делает Ondello с потоками.

Тем не менее, здесь приведен код старого проекта для android / RTSP / SDP / RTP с использованием «netty» и «efflux». Он будет обсуждать некоторые части «Сессии» для поставщиков файлов SDP. Не могу вспомнить, будет ли это на самом деле воспроизводить звуковую часть материала Youtube / RTSP , но в этом моя цель была в то время. (Я думаю, что он работал с использованием кодека AMR-NB, но было много проблем, и я потерял RTSP на Android, как плохая привычка!)

На Гит ….

  @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"); } } 

К сожалению, невозможно воспроизвести RTP-поток с помощью Android MediaPlayer.

Решения этих проблем включают в себя декодирование потока RTP с помощью ffmpeg. Учебники по сборке ffmpeg для Android можно найти в Интернете.