2013-03-16 2 views
0

Я изучаю Xuggler (библиотека поддерживает потоковое видео для Java), следуя коду в преподавании tutorialhow to decode and play video.Ошибка с расшифровкой java-видео от Xuggler

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

Exception in thread "main" java.lang.RuntimeException: got error decoding video in: C:/Users/swnmlab/1.mp4

Эта ошибка происходит, когда эта линия получила казнены

int bytesDecoded = videoCoder.decodeVideo(picture, packet,offset);

Я использовал отладчик шагнуть и найти что-xuggle xuggler.jar не имеет никакой привязанности источника, кто-нибудь сталкивался с этой проблемой раньше?

import java.awt.image.BufferedImage; 

import com.xuggle.xuggler.ICodec.Type; 
import com.xuggle.xuggler.IContainer; 
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.demos.VideoImage; 

public class DecodeAndPlayVideo { 
    public static void main(String[] args) { 
     String filename = "C:/Users/swnmlab/1.mp4"; 

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

     // Open up the container 
     if (container.open(filename, IContainer.Type.READ, null) < 0) 
      throw new IllegalArgumentException("could not open file: " 
        + filename); 

     // 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() == Type.CODEC_TYPE_VIDEO) { 
       videoStreamId = i; 
       videoCoder = coder; 
       break; 
      } 
     } 
     if (videoStreamId == -1) 
      throw new RuntimeException(
        "could not find video stream in container: " + filename); 

     if (videoCoder.acquire() < 0) 
      throw new RuntimeException(
        "could not open video decoder for container: " + filename); 

     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: " + filename); 
     } 

     /* 
     * And once we have that, we draw a window on screen 
     */ 
     openJavaWindow(); 

     IPacket packet = IPacket.make(); 
     while (container.readNextPacket(packet) >= 0) { 
      /* 
      * Now we have a packet, let's see if it belongs to our video stream 
      */ 
      if (packet.getStreamIndex() == videoStreamId) { 
       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: " + filename); 
        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: " 
               + filename); 
         } 
         if (newPic.getPixelType() != IPixelFormat.Type.BGR24) 
          throw new RuntimeException("could not decode video" 
            + " as BGR 24 bit data in: " + filename); 


         @SuppressWarnings("deprecation") 
         BufferedImage javaImage = Utils.videoPictureToImage(newPic); 

         // and display it on the Java Swing window 
         updateJavaWindow(javaImage);  
        } 

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

     closeJavaWindow(); 

    } 

    private static VideoImage mScreen = null; 
    private static void updateJavaWindow(BufferedImage javaImage) { 
     mScreen.setImage(javaImage); 
    } 

    private static void openJavaWindow() { 
     mScreen = new VideoImage(); 
    } 

    private static void closeJavaWindow() { 
     System.exit(0); 
    } 
} 

P.S. Если вы хотите попробовать эту библиотеку, вы можете найти установочный файл here, а затем выполните следующие действия: this page завершите установку этой библиотеки в Windows.


я обнаружил, произошла ошибка, потому что я cahnged исходного кода

 if (videoCoder.open() < 0) 
      throw new RuntimeException(
        "could not open video decoder for container: " + filename); 

в

 if (videoCoder.acquire() < 0) 
      throw new RuntimeException(
        "could not open video decoder for container: " + filename); 

так открыты() метод вызывает предупреждение устаревания, так что я использовал автозаполнение, чтобы найти метод, который выглядит как open(), а затем изменен на приобретать(). Я думал, что все в порядке, так как «невозможно открыть видеодекодер для контейнера: исключение исключено». Просто следуйте образцу кода.

ответ

1

Я просмотрел ваш код и обнаружил, что вы получили videoCoder, но вы не сделали open перед игрой. Возможно, поэтому вы не можете его расшифровать. Так вы могли бы попробовать? Метод

if (videoCoder.open() < 0) 
    throw new RuntimeException(
      "could not open video decoder for container: " 
        + filename); 
IVideoResampler resampler = null; 
+0

Erh ... мой файл "C: /Users/swnmlab/1.mp4", это видеофайл ... –

+0

Извините, моя вина. Обновлен мой ответ. – longhua

+0

Спасибо ~ Я нашел ошибку из-за подсказки в вашем ответе! Я отредактирую свой вопрос. –

4

открыт() является устаревшим, вы должны использовать открытые (NULL, NULL) вместо

if (videoCoder.open(null,null) < 0) 
throw new RuntimeException(
     "could not open video decoder for container: " 
       + filename); 
1

я выполнил тот же код со следующими изменениями кода. Эти изменения требовались, поскольку ниже API устарели.

IMetaData params = IMetaData.make(); 
IContainerParameters params = IContainerParameters.make(); 

Как показано, я использовал видеокодер для установки времени, высоты и ширины.

if (coder.getCodecType() == ICodec.Type.CODEC_TYPE_VIDEO) 
    { 
    videoStreamId = i; 
    videoCoder = coder; 

    // The timebase here is used as the camera frame rate  
    videoCoder.setTimeBase(IRational.make(30,1)); 

    // we need to tell the driver what video with and height to use 
    videoCoder.setWidth(320); 
    videoCoder.setHeight(240); 

    break; 
    } 

Тем не менее, я столкнулся с другой проблемой, что дисплей веб-камера занимающих весь экран, а не на заданной ширины и высоты.

Неверный код, который задает высоту и ширину? Как мы должны контролировать размер?

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