2012-02-17 24 views
27

Có ai có thể giới thiệu thư viện Java cho phép tôi tạo video theo chương trình không? Cụ thể, nó sẽ làm như sau:Thư viện Java được đề xuất để tạo video theo chương trình

  • tham gia một loạt các BufferedImages như các khung
  • phép một nền WAV/MP3 sang được thêm
  • phép 'ngẫu nhiên' WAV/MP3 để được thêm vào tùy tiện, các điểm được chỉ định theo chương trình
  • xuất video theo định dạng chung (MPEG, v.v.)

Ai có thể đề xuất bất cứ điều gì không? Đối với hình ảnh/âm thanh trộn, tôi thậm chí còn sống với một cái gì đó mà đã lấy một loạt các khung hình, và cho mỗi khung tôi đã phải cung cấp các byte thô của dữ liệu âm thanh không nén liên kết với khung đó.

P.S. Nó thậm chí không phải là một "thư viện của bên thứ ba" như vậy nếu Java Media Framework có các cuộc gọi để đạt được ở trên, nhưng từ bộ nhớ sơ sài của tôi, tôi có một cảm giác nó không.

+0

Bạn có thể thử này. http://wiki.xuggle.com/MediaTool_Introduction – Ovilia

+0

Tôi nhìn vào Xích, nhưng nó không một nửa trông giống như một nỗi đau trong ass để thiết lập. Không chắc chắn lý do tại sao những người này có một khối tâm thần với chỉ cho bạn một cái bình/dll/exe để tải xuống ... –

+0

P.S. Hiện tại, tôi có một giải pháp-- đang chờ mọi thứ tốt hơn-- là lưu các khung hình, ví dụ: Các tệp PNG sau đó gọi tiện ích dòng lệnh ffmpeg trên các khung. Tôi cho rằng đó là những gì một thư viện có thể thực hiện dưới mui xe. –

Trả lời

5

Tôi đã sử dụng mã được đề cập bên dưới để thực hiện thành công các mục 1, 2 và 4 trên danh sách yêu cầu của bạn bằng Java thuần túy. Nó có giá trị và bạn có thể tìm ra cách để bao gồm # 3.

http://www.randelshofer.ch/blog/2010/10/writing-quicktime-movies-in-pure-java/

+0

Đây chắc chắn là chức năng gần với đặc điểm kỹ thuật tôi đã đề cập. Như tôi thấy, nhược điểm chính là nó hợp nhất hiệu quả các khung hình riêng lẻ hơn là sử dụng codec video, vì vậy bạn kết thúc với các tệp lớn hơn. Mặt khác, tôi thích ý tưởng không có vấn đề về sáng chế. –

4

Tôi tìm thấy một công cụ gọi là ffmpeg mà có thể chuyển đổi các file đa phương tiện hình thành một định dạng khác. Có một bộ lọc được gọi là libavfilter trong ffmpeg, đây là phần thay thế cho vhook, cho phép chỉnh sửa hoặc kiểm tra video/audio giữa bộ giải mã và bộ mã hóa. Tôi nghĩ rằng có thể nhập khung hình thô và tạo video. Tôi đã nghiên cứu về bất kỳ triển khai java nào của ffmpeg và tìm thấy trang có tiêu đề "Getting Started with FFMPEG-JAVA" là trình bao bọc JAVA xung quanh FFMPEG bằng cách sử dụng JNA.

+0

Cảm ơn - Tôi chắc chắn sẽ kiểm tra điều này ở một số giai đoạn! –

-1

Hãy thử JavaFX.

JavaFX bao gồm hỗ trợ hiển thị hình ảnh ở nhiều định dạng và hỗ trợ phát lại âm thanh và video trên tất cả các nền tảng mà JavaFX được hỗ trợ.

Here là một hướng dẫn về thao tác hình ảnh

Here là một hướng dẫn về việc tạo ra trình chiếu, mốc thời gian và hậu trường.

Here là Câu hỏi thường gặp về cách thêm âm thanh.

Hầu hết trong số này là trên JavaFX 1.3. Bây giờ JavaFX 2.0 đã hết.

0

Tại sao không sử dụng FFMPEG?

Có vẻ là một wrapper Java cho nó:

http://fmj-sf.net/ffmpeg-java/getting_started.php

Dưới đây là một ví dụ về cách biên dịch các nguồn phương tiện truyền thông khác nhau vào một video với FFMPEG:

http://howto-pages.org/ffmpeg/#multiple

Và , cuối cùng, tài liệu:

http://ffmpeg.org/ffmpeg.html

+0

Vì vậy, tại thời điểm này tôi đang thực sự sử dụng FFMPEG, mặc dù trong một cách hơi clunky bởi vì tôi đã không tìm ra cách sử dụng tất cả các tùy chọn. ATM Tôi đang lưu tất cả các khung hình dưới dạng hình ảnh trong một thư mục, sau đó chạy FFMPEG trên chúng. Tôi giả sử có một cách để ống các khung hình trực tiếp từng người một để FFMPEG mà không cần phải lưu chúng, nhưng đã không figured này ra được nêu ra. Tôi nghĩ rằng có thể đã có một thư viện đã làm điều này, ví dụ. –

1

Bạn có thể thử một thư viện codec Java thuần túy có tên JCodec.
Nó có bộ mã hóa H.264 (AVC) rất cơ bản và muxer MP4. Dưới đây là mã mẫu đầy đủ được lấy từ mẫu của chúng - TranscodeMain.

private static void png2avc(String pattern, String out) throws IOException { 
    FileChannel sink = null; 
    try { 
     sink = new FileOutputStream(new File(out)).getChannel(); 
     H264Encoder encoder = new H264Encoder(); 
     RgbToYuv420 transform = new RgbToYuv420(0, 0); 

     int i; 
     for (i = 0; i < 10000; i++) { 
      File nextImg = new File(String.format(pattern, i)); 
      if (!nextImg.exists()) 
       continue; 
      BufferedImage rgb = ImageIO.read(nextImg); 
      Picture yuv = Picture.create(rgb.getWidth(), rgb.getHeight(), ColorSpace.YUV420); 
      transform.transform(AWTUtil.fromBufferedImage(rgb), yuv); 
      ByteBuffer buf = ByteBuffer.allocate(rgb.getWidth() * rgb.getHeight() * 3); 

      ByteBuffer ff = encoder.encodeFrame(buf, yuv); 
      sink.write(ff); 
     } 
     if (i == 1) { 
      System.out.println("Image sequence not found"); 
      return; 
     } 
    } finally { 
     if (sink != null) 
      sink.close(); 
    } 
} 

Mẫu này là phức tạp hơn và thực sự cho thấy muxing của khung mã hóa vào tập tin MP4:

private static void prores2avc(String in, String out, ProresDecoder decoder, RateControl rc) throws IOException { 
    SeekableByteChannel sink = null; 
    SeekableByteChannel source = null; 
    try { 
     sink = writableFileChannel(out); 
     source = readableFileChannel(in); 

     MP4Demuxer demux = new MP4Demuxer(source); 
     MP4Muxer muxer = new MP4Muxer(sink, Brand.MOV); 

     Transform transform = new Yuv422pToYuv420p(0, 2); 

     H264Encoder encoder = new H264Encoder(rc); 

     MP4DemuxerTrack inTrack = demux.getVideoTrack(); 
     CompressedTrack outTrack = muxer.addTrackForCompressed(TrackType.VIDEO, (int) inTrack.getTimescale()); 

     VideoSampleEntry ine = (VideoSampleEntry) inTrack.getSampleEntries()[0]; 
     Picture target1 = Picture.create(ine.getWidth(), ine.getHeight(), ColorSpace.YUV422_10); 
     Picture target2 = null; 
     ByteBuffer _out = ByteBuffer.allocate(ine.getWidth() * ine.getHeight() * 6); 

     ArrayList<ByteBuffer> spsList = new ArrayList<ByteBuffer>(); 
     ArrayList<ByteBuffer> ppsList = new ArrayList<ByteBuffer>(); 
     Packet inFrame; 
     int totalFrames = (int) inTrack.getFrameCount(); 
     long start = System.currentTimeMillis(); 
     for (int i = 0; (inFrame = inTrack.getFrames(1)) != null && i < 100; i++) { 
      Picture dec = decoder.decodeFrame(inFrame.getData(), target1.getData()); 
      if (target2 == null) { 
       target2 = Picture.create(dec.getWidth(), dec.getHeight(), ColorSpace.YUV420); 
      } 
      transform.transform(dec, target2); 
      _out.clear(); 
      ByteBuffer result = encoder.encodeFrame(_out, target2); 
      if (rc instanceof ConstantRateControl) { 
       int mbWidth = (dec.getWidth() + 15) >> 4; 
       int mbHeight = (dec.getHeight() + 15) >> 4; 
       result.limit(((ConstantRateControl) rc).calcFrameSize(mbWidth * mbHeight)); 
      } 
      spsList.clear(); 
      ppsList.clear(); 
      H264Utils.encodeMOVPacket(result, spsList, ppsList); 
      outTrack.addFrame(new MP4Packet((MP4Packet) inFrame, result)); 
      if (i % 100 == 0) { 
       long elapse = System.currentTimeMillis() - start; 
       System.out.println((i * 100/totalFrames) + "%, " + (i * 1000/elapse) + "fps"); 
      } 
     } 
     outTrack.addSampleEntry(H264Utils.createMOVSampleEntry(spsList, ppsList)); 

     muxer.writeHeader(); 
    } finally { 
     if (sink != null) 
      sink.close(); 
     if (source != null) 
      source.close(); 
    } 
} 
Các vấn đề liên quan