2013-11-27 29 views
0

我試圖將實時RTMP流視頻從link1轉發到link2。但是當視頻在輸入端停止或暫停時,我的Java應用程序將停止讀取數據包,並收到錯誤'無法讀取RTMP-Header數據包'。代碼如下所示 -無法使用Xuggler連續發佈實時流而沒有任何通過RTMP向FMS停止

import com.xuggle.xuggler.ICodec; 
import com.xuggle.xuggler.IContainer; 
import com.xuggle.xuggler.IContainerFormat; 
import com.xuggle.xuggler.IPacket; 
import com.xuggle.xuggler.IStream; 
import com.xuggle.xuggler.IStreamCoder; 
import com.xuggle.xuggler.IVideoPicture; 

public class XugglerRecorder 
{ 
    public static void main(String[] args) 
    { 
     String url = "rtmp://IP:PORT/live2/16_8_2013"; 

     IContainer readContainer = IContainer.make(); 
     readContainer.setInputBufferLength(4096); 
     IContainer writeContainer=IContainer.make(); 
     //writeContainer.setInputBufferLength(0); 
     IContainerFormat containerFormat_live = IContainerFormat.make(); 
     containerFormat_live.setOutputFormat("flv","rtmp://IP:PORT/live/abc", null); 
     int retVal= writeContainer.open("rtmp://192.168.1.198:1935/live/abc", IContainer.Type.WRITE, containerFormat_live); 
     //writeContainer.setInputBufferLength(0); 
     if (retVal < 0) { 
      System.err.println("Could not open output container for live stream"); 
      System.exit(1); 
     } 

     if (readContainer.open(url, IContainer.Type.READ, null, true, false) < 0) { 
      throw new RuntimeException("unable to open read container"); 
     } 

     IStream video = writeContainer.addNewStream(0); 
     if (video == null) { 
      throw new RuntimeException("unable to add video stream"); 
     } 

     IPacket packet = IPacket.make(); 
     while (readContainer.readNextPacket(packet) >= 0 && !packet.isKeyPacket()) {} 

     IStreamCoder inVideoCoder = null; 
     int videoStreamId = -1; 
     for (int i = 0; i < readContainer.getNumStreams(); ++i) { 
      IStream stream = readContainer.getStream(i); 
      IStreamCoder coder = stream.getStreamCoder(); 
      if (coder.getCodecType() == ICodec.Type.CODEC_TYPE_VIDEO) { 
       inVideoCoder = coder; 
       videoStreamId = i; 

       if (inVideoCoder.open(null, null) < 0) { 
        throw new RuntimeException("Unable to open input video coder"); 
       } 

       //for getting frame params need to decode at least one key frame 
       IVideoPicture picture = IVideoPicture.make(inVideoCoder.getPixelType(), 0, 0); 

       int bytesDecoded = inVideoCoder.decodeVideo(picture, packet, 0); 
       if (bytesDecoded < 0) { 
        throw new RuntimeException("Unable to decode video packet"); 
       } 
      } 
     } 

     if (videoStreamId == -1) { 
      throw new RuntimeException("unable to find video stream"); 
     }   

     IStreamCoder outVideoCoder = video.getStreamCoder(); 
     outVideoCoder.setCodec(inVideoCoder.getCodec()); 
     outVideoCoder.setHeight(inVideoCoder.getHeight()); 
     outVideoCoder.setWidth(inVideoCoder.getWidth()); 
     outVideoCoder.setPixelType(inVideoCoder.getPixelType()); 
     outVideoCoder.setBitRate(inVideoCoder.getBitRate()); 
     outVideoCoder.setTimeBase(inVideoCoder.getTimeBase()); 
     if (outVideoCoder.open(null, null) < 0) { 
      throw new RuntimeException("unable to open output video coder"); 
     } 

     if (writeContainer.writeHeader() < 0) { 
      throw new RuntimeException("unable to write header"); 
     } 

     int i = 0; 
     doit(readContainer, packet, writeContainer); 
     if (writeContainer.writeTrailer() < 0) { 
      throw new RuntimeException("unable to write trailer"); 
     } 

    } 

    private static void doit(IContainer readContainer, IPacket packet, 
      IContainer writeContainer) { 
     int i = 0; 
     while (readContainer.readNextPacket(packet) >= 0) { 
      if(readContainer.readNextPacket(packet)<0) 
      { 
       System.out.println("Packet null Hello"); 
       try{ 
        doit(readContainer, packet, writeContainer);    
       }catch(Exception e){e.printStackTrace();} 
       continue; 
      } 

      if(readContainer.readNextPacket(packet)==-1){ 
       System.out.println("Packet is absent"); 
      } 

      if (packet.getStreamIndex() != 0) { 
       continue; 
      } 

      if (writeContainer.writePacket(packet) < 0 && readContainer.readNextPacket(packet)>=0) { 
       try{ 
        System.out.println(" packet sleep"); 
       }catch(Exception e){e.printStackTrace();} 
      } 

     }  
    } 
} 

我能夠通過RTMP向FMS發佈實時視頻。但在視頻流停止或暫停之前無法存儲視頻的保存點。如果輸入流有任何時間滯後,那麼我的應用程序應該繼續檢查並等待流而不是停止。 請幫我解決這個問題。提前致謝。

任何幫助或提示如何調試這將非常感激。

+0

我也在研究相同的應用程序,但我有一個問題,我需要從攝像頭並排錄製視頻,我需要將此視頻發佈到RTMP服務器(wowza媒體服務器)。上面的帖子可以做嗎? – Aniket

回答

0

我對Xuggler瞭解不多。

您可能會嘗試捕捉異常。

或者您可以嘗試在main方法中多次調用doit()。假設萬一沒有更多的數據包在那裏讀取,那麼方法就會被忽略。所以,它不會再嘗試讀取。

或者你可以嘗試在DOIT(起點添加類似 而(container.readPacket == NULL){})或我認爲這將是 而(container.readPacket!= NULL){}

不要檢查isKeyPacket,看看會發生什麼。

相關問題