2012-07-25 2 views
5

Screen Recorder with Audio을 java에서 xuggler을 사용하여 개발 중입니다. 비디오 파일과 오디오 파일을 별도로 만들었습니다. 이제 두 파일을 동기화하려고합니다. "ConcatenateAudioAndVideo.java"를 사용하여 시도했지만 파일을 실행할 때 44bytes 파일 만 생성합니다. 아무도 문제를 말해 줄 수 있습니까? 미리 감사드립니다. xuggler를 사용하여 오디오 및 비디오를 동기화하는 방법

답변

13

두 개의 파일 (오디오 및 비디오) 동기화 문제도 발생했습니다. 인터넷에서이 작업을 수행하는 데 필요한 팁은 많이 있지만 완전한 코드 예제는 아닙니다. xuggler를 사용하여 코드를 작성하여 해결했습니다. 여기에 코드가 있습니다. 질문이 있으시면 언제든지 물어보십시오. 나는 너를 도울 것이다. 이 코드는 다음과 같습니다.

import com.xuggle.mediatool.IMediaWriter; 
import com.xuggle.mediatool.ToolFactory; 
import com.xuggle.xuggler.IAudioSamples; 
import com.xuggle.xuggler.ICodec; 
import com.xuggle.xuggler.IContainer; 
import com.xuggle.xuggler.IPacket; 
import com.xuggle.xuggler.IStream; 
import com.xuggle.xuggler.IStreamCoder; 
import com.xuggle.xuggler.IVideoPicture; 


/** 
* This class is used to merge audio and video file. 
* 
* @author Arslaan Ejaz 
*/ 
public class DecodeAndSaveAudioVideo { 

public static void main(String[] args) 
    { 

    String filenamevideo = "f:/testvidfol/video.mp4"; //this is the input file for video. you can change extension 
    String filenameaudio = "f:/testvidfol/audio.wav"; //this is the input file for audio. you can change extension 


    IMediaWriter mWriter = ToolFactory.makeWriter("f:/testvidfol/audiovideooutput.flv"); //output file 

    IContainer containerVideo = IContainer.make(); 
    IContainer containerAudio = IContainer.make(); 

    if (containerVideo.open(filenamevideo, IContainer.Type.READ, null) < 0) 
     throw new IllegalArgumentException("Cant find " + filenamevideo); 

    if (containerAudio.open(filenameaudio, IContainer.Type.READ, null) < 0) 
     throw new IllegalArgumentException("Cant find " + filenameaudio); 

    int numStreamVideo = containerVideo.getNumStreams(); 
    int numStreamAudio = containerAudio.getNumStreams(); 

    System.out.println("Number of video streams: "+numStreamVideo + "\n" + "Number of audio streams: "+numStreamAudio); 

int videostreamt = -1; //this is the video stream id 
int audiostreamt = -1; 

IStreamCoder videocoder = null; 

    for(int i=0; i<numStreamVideo; i++){ 
     IStream stream = containerVideo.getStream(i); 
     IStreamCoder code = stream.getStreamCoder(); 

     if(code.getCodecType() == ICodec.Type.CODEC_TYPE_VIDEO) 
     { 
      videostreamt = i; 
      videocoder = code; 
      break; 
     } 

    } 

    for(int i=0; i<numStreamAudio; i++){ 
     IStream stream = containerAudio.getStream(i); 
     IStreamCoder code = stream.getStreamCoder(); 

     if(code.getCodecType() == ICodec.Type.CODEC_TYPE_AUDIO) 
     { 
      audiostreamt = i; 
      break; 
     } 

    } 

    if (videostreamt == -1) throw new RuntimeException("No video steam found"); 
    if (audiostreamt == -1) throw new RuntimeException("No audio steam found"); 

    if(videocoder.open()<0) throw new RuntimeException("Cant open video coder"); 
    IPacket packetvideo = IPacket.make(); 

    IStreamCoder audioCoder = containerAudio.getStream(audiostreamt).getStreamCoder(); 

    if(audioCoder.open()<0) throw new RuntimeException("Cant open audio coder"); 
    mWriter.addAudioStream(1, 1, audioCoder.getChannels(), audioCoder.getSampleRate()); 

    mWriter.addVideoStream(0, 0, videocoder.getWidth(), videocoder.getHeight()); 

    IPacket packetaudio = IPacket.make(); 

    while(containerVideo.readNextPacket(packetvideo) >= 0 || 
      containerAudio.readNextPacket(packetaudio) >= 0){ 

     if(packetvideo.getStreamIndex() == videostreamt){ 

      //video packet 
      IVideoPicture picture = IVideoPicture.make(videocoder.getPixelType(), 
        videocoder.getWidth(), 
        videocoder.getHeight()); 
      int offset = 0; 
      while (offset < packetvideo.getSize()){ 
       int bytesDecoded = videocoder.decodeVideo(picture, 
         packetvideo, 
         offset); 
       if(bytesDecoded < 0) throw new RuntimeException("bytesDecoded not working"); 
       offset += bytesDecoded; 

       if(picture.isComplete()){ 
        System.out.println(picture.getPixelType()); 
        mWriter.encodeVideo(0, picture); 

       } 
      } 
     } 

     if(packetaudio.getStreamIndex() == audiostreamt){ 
     //audio packet 

      IAudioSamples samples = IAudioSamples.make(512, 
        audioCoder.getChannels(), 
        IAudioSamples.Format.FMT_S32); 
      int offset = 0; 
      while(offset<packetaudio.getSize()) 
      { 
       int bytesDecodedaudio = audioCoder.decodeAudio(samples, 
         packetaudio, 
         offset); 
       if (bytesDecodedaudio < 0) 
        throw new RuntimeException("could not detect audio"); 
       offset += bytesDecodedaudio; 

       if (samples.isComplete()){ 
        mWriter.encodeAudio(1, samples); 

     } 
      } 

    } 

    } 
} 
} 
+0

@arslaan ejaz 나는 ur 코드를 시도했지만, 라이브러리 및 특히 여기에 사용 된 버전이 무엇인지 알고 싶습니다. 다음 오류가 발생합니다 :'예외 스레드 "main"java.lang.NoSuchMethodError : org.slf4j.Logger.trace (Ljava/lang/String; Ljava/lang/Object;) V' –

+0

xuggler를 포함한 openimaj 라이브러리 5.4. youtube link : www.youtube.com/watch?v=TNEQ0eNqLgA –

+0

@arslaan ejaz : 오디오 파일로 동영상을 찾는 데 나를 도울 수 있습니까? 성공적으로 오디오 비디오 파일을 만들었지 만 MAC os에서 검색하는 데 문제가 있습니다 ... 알고 계시다면 – tarkikshah