2015-11-06 1 views
0

Я пробовал последние две недели для записи с веб-камеры в файл, но мне не удалось получить API-интерфейс Webcam Capture, работающий на моей малиновой модели Pi B +.Можно ли записывать видео с веб-камеры в файл только с помощью Xuggle Xuggler?

Приложение запускается, но оно замерзает в конце без каких-либо ошибок консоли.

Java source code, который записывается с веб-камеры, но замораживается в конце и оставляет 100% -ное использование ЦП до тех пор, пока оно не будет завершено ctrl + c.

Xuggle Xuggler, похоже, работает нормально, но возможно ли записывать видео только с помощью Xuggle Xuggler?

Я нашел демо для Xuggle Xuggler, но ни один из этих файла записи с веб-камеры

Xuggle Xuggler java demos

Так что же можно записывать видео с помощью xuggle Xuggler и Java библиотеки или это просто снова трата время?

ответ

0

Казалось, что это не просто трата времени ...

Исходный код ниже будет захватывать видео в файл, используя только библиотеки Xuggle Xuggler и Java. Исходный код будет работать при использовании только разрешения 320x240 или выше, так как xuggle xugglers lousy webcam support.

Я все еще жду лучшего и быстрого решения для моей оригинальной проблемы, которая будет принята в качестве ответа.

package webcam; 

import com.xuggle.mediatool.IMediaWriter; 
import com.xuggle.mediatool.ToolFactory; 
import com.xuggle.xuggler.ICodec; 
import com.xuggle.xuggler.IContainer; 
import com.xuggle.xuggler.IContainerFormat; 
import com.xuggle.xuggler.IError; 
import com.xuggle.xuggler.IMetaData; 
import com.xuggle.xuggler.IPacket; 
import com.xuggle.xuggler.IPixelFormat; 
import com.xuggle.xuggler.IStream; 
import com.xuggle.xuggler.IStreamCoder; 
import com.xuggle.xuggler.IVideoPicture; 
import com.xuggle.xuggler.IVideoResampler; 
import com.xuggle.xuggler.Utils; 
import com.xuggle.xuggler.video.ConverterFactory; 
import com.xuggle.xuggler.video.IConverter; 
import java.awt.image.BufferedImage; 
import java.io.File; 


public class Uusi { 

    @SuppressWarnings("deprecation") 
    public static void main(String[] args) throws Throwable { 

     File file = new File("output.h264"); 
     IMediaWriter writer = ToolFactory.makeWriter(file.getName()); 

     writer.addVideoStream(0, 0, ICodec.ID.CODEC_ID_H264, 320, 240); 

     String driverName = "vfwcap"; 
     String deviceName = "0"; 

     // Let's make sure that we can actually convert video pixel formats. 
     if (!IVideoResampler.isSupported(IVideoResampler.Feature.FEATURE_COLORSPACECONVERSION)) { 
      throw new RuntimeException("you must install the GPL version of Xuggler (with IVideoResampler support) for this demo to work"); 
     } 

     // Create a Xuggler container object 
     IContainer container = IContainer.make(); 

     // Tell Xuggler about the device format 
     IContainerFormat format = IContainerFormat.make(); 
     if (format.setInputFormat(driverName) < 0) { 
      throw new IllegalArgumentException("couldn't open webcam device: " + driverName); 
     } 

     // devices, unlike most files, need to have parameters set in order 
     // for Xuggler to know how to configure them, for a webcam, these 
     // parameters make sense 
     IMetaData params = IMetaData.make(); 

     params.setValue("framerate", "30/1"); 
     params.setValue("video_size", "320x240"); 


     // Open up the container 
     int retval = container.open(deviceName, IContainer.Type.READ, format, 
       false, true, params, null); 
     if (retval < 0) { 
      // This little trick converts the non friendly integer return value into 
      // a slightly more friendly object to get a human-readable error name 
      IError error = IError.make(retval); 
      throw new IllegalArgumentException("could not open file: " + deviceName + "; Error: " + error.getDescription()); 
     } 

     // query how many streams the call to open found 
     int numStreams = container.getNumStreams(); 

     // and iterate through the streams to find the first video stream 
     int videoStreamId = -1; 
     IStreamCoder videoCoder = null; 
     for (int i = 0; i < numStreams; i++) { 
      // Find the stream object 
      IStream stream = container.getStream(i); 
      // Get the pre-configured decoder that can decode this stream; 
      IStreamCoder coder = stream.getStreamCoder(); 

      if (coder.getCodecType() == ICodec.Type.CODEC_TYPE_VIDEO) { 
       videoStreamId = i; 
       videoCoder = coder; 
       break; 
      } 
     } 
     if (videoStreamId == -1) { 
      throw new RuntimeException("could not find video stream in container: " + deviceName); 
     } 

     /* 
     * Now we have found the video stream in this file. Let's open up our decoder so it can 
     * do work. 
     */ 
     if (videoCoder.open() < 0) { 
      throw new RuntimeException("could not open video decoder for container: " + deviceName); 
     } 

     IVideoResampler resampler = null; 
     if (videoCoder.getPixelType() != IPixelFormat.Type.BGR24) { 
      // if this stream is not in BGR24, we're going to need to 
      // convert it. The VideoResampler does that for us. 
      resampler = IVideoResampler.make(videoCoder.getWidth(), videoCoder.getHeight(), IPixelFormat.Type.BGR24, 
        videoCoder.getWidth(), videoCoder.getHeight(), videoCoder.getPixelType()); 
      if (resampler == null) { 
       throw new RuntimeException("could not create color space resampler for: " + deviceName); 
      } 
     } 


     /* 
     * Now, we start walking through the container looking at each packet. 
     */ 
     IPacket packet = IPacket.make(); 

     long start = System.currentTimeMillis(); 
     int i = 0; 
     while (container.readNextPacket(packet) >= 0 && i < 100) { 
      /* 
      * Now we have a packet, let's see if it belongs to our video stream 
      */ 
      if (packet.getStreamIndex() == videoStreamId) { 
       /* 
       * We allocate a new picture to get the data out of Xuggler 
       */ 
       IVideoPicture picture = IVideoPicture.make(videoCoder.getPixelType(), 
         videoCoder.getWidth(), videoCoder.getHeight()); 

       int offset = 0; 
       while (offset < packet.getSize()) { 
        /* 
        * Now, we decode the video, checking for any errors. 
        * 
        */ 
        int bytesDecoded = videoCoder.decodeVideo(picture, packet, offset); 
        if (bytesDecoded < 0) { 
         throw new RuntimeException("got error decoding video in: " + deviceName); 
        } 
        offset += bytesDecoded; 

        /* 
        * Some decoders will consume data in a packet, but will not be able to construct 
        * a full video picture yet. Therefore you should always check if you 
        * got a complete picture from the decoder 
        */ 
        if (picture.isComplete()) { 
         IVideoPicture newPic = picture; 
         /* 
         * If the resampler is not null, that means we didn't get the video in BGR24 format and 
         * need to convert it into BGR24 format. 
         */ 
         if (resampler != null) { 
          // we must resample 
          newPic = IVideoPicture.make(resampler.getOutputPixelFormat(), picture.getWidth(), picture.getHeight()); 
          if (resampler.resample(newPic, picture) < 0) { 
           throw new RuntimeException("could not resample video from: " + deviceName); 
          } 
         } 
         if (newPic.getPixelType() != IPixelFormat.Type.BGR24) { 
          throw new RuntimeException("could not decode video as BGR 24 bit data in: " + deviceName); 
         } 

         // Convert the BGR24 to an Java buffered image 
         BufferedImage javaImage = Utils.videoPictureToImage(newPic); 

         System.out.println("Capture frame " + i); 

         BufferedImage image = ConverterFactory.convertToType(javaImage, BufferedImage.TYPE_3BYTE_BGR); 
         IConverter converter = ConverterFactory.createConverter(image, IPixelFormat.Type.YUV420P); 

         IVideoPicture frame = converter.toPicture(image, (System.currentTimeMillis() - start) * 1000); 
         frame.setKeyFrame(i == 0); 
         frame.setQuality(0); 

         writer.encodeVideo(0, frame);   

         i++; 
        } 

       } 

      } else { 
       /* 
       * This packet isn't part of our video stream, so we just silently drop it. 
       */ 
       do { 
       } while (false); 
      } 

     } 

     writer.close(); 

     System.out.println("Video recorded in file: " + file.getAbsolutePath()); 
    } 
} 

UPDATE: При тестировании выше кода на Raspberry Pi Model B +, он записывает видео, но при просмотре записанного видео, кажется, что в «фаст-fordward» -Режим. Таким образом, код не очень хорош, потому что малина требует гораздо больше времени при кодировании видео, чем мощный ноутбук (Windows 8.1).

Смежные вопросы