Java-Gaming.org    
Featured games (79)
games approved by the League of Dukes
Games in Showcase (477)
Games in Android Showcase (109)
games submitted by our members
Games in WIP (536)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
  JavaGaming.org - Pastebin



Author: Riven (posted 2012-08-10 20:31:56, viewed 96 times)

1   2   3   4   5   6   7   8   9   10   11   12   13   14   15   16   17   18   19   20   21   22   23   24   25   26   27   28   29   30   31   32   33   34   35   36   37   38   39   40   41   42   43   44   45   46   47   48   49   50   51   52   53   54   55   56   57   58   59   60   61   62   63   64   65   66   67   68   69   70   71   72   73   74   75   76   77   78   79   80   81   82   83   84   85   86   87   88   89   90   91   92   93   94   95   96   97   98   99   100   101   102   103   104   105   106   107   108   109   110   111   112   113   114   115   116   117   118   119   120   121   122   123   124   125   126   127   128   129   130   131   132   133   134   135   136   137   138   139   140   141   142   143   144   145   146   147   148   149   150   151   152   153   154   155   156   157   158   159   160   161   162   163   164   165   166   167   168   169   170   171   172   173   174   175   176   177   178  
package main.vlc;

import java.awt.Canvas;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;

import javax.imageio.ImageIO;

import craterstudio.misc.ImageUtil;
import craterstudio.util.HighLevel;
import craterstudio.util.concur.SimpleBlockingQueue;

public abstract class AbstractVideoPlayback {

   public AbstractVideoPlayback() {
      this.frameDataQueue = new SimpleBlockingQueue<>(2);
      this.frameImageQueue = new SimpleBlockingQueue<>(2);
   }

   final SimpleBlockingQueue<byte[]> frameDataQueue;
   final SimpleBlockingQueue<BufferedImage> frameImageQueue;

   void startVideo(String title) {
      this.startReadLoop();
      this.startDecodeLoop();
      this.startDisplayLoop(title);
   }

   void startReadLoop() {
      new Thread(new Runnable() {
         @Override
         public void run() {
            runReadLoop();
         }
      }).start();
   }

   void startDecodeLoop() {
      new Thread(new Runnable() {
         @Override
         public void run() {
            runDecodeLoop();
         }
      }).start();
   }

   void startDisplayLoop(final String windowTitle) {
      new Thread(new Runnable() {
         @Override
         public void run() {
            runDisplayLoop(windowTitle);
         }
      }).start();
   }

   abstract void runReadLoop();

   void runDecodeLoop() {
      while (true) {
         byte[] data = frameDataQueue.take();
         if (data == null) {
            break;
         }

         BufferedImage image;
         try {
            if (data[0] == 0 && data[1] == 0) // TGA
               image = ImageUtil.readTGA(new ByteArrayInputStream(data), data.length);
            else
               image = ImageIO.read(new ByteArrayInputStream(data));
         } catch (Exception exc) {
            continue;
         }
         if (image == null) {
            continue;
         }

         frameImageQueue.put(image);
      }

      frameImageQueue.put(null);

      System.out.println("Data Queue: EOF");
   }

   public int getFrameFrequency() {
      return -1;
   }

   public void tickAudio() {
   }

   public void runDisplayLoop(String windowTitle) {
      BufferedImage image = frameImageQueue.take();
      if (image == null) {
         System.out.println("no initial frame");
         return;
      }
      Dimension dim = new Dimension(image.getWidth(), image.getHeight());
      System.out.println(dim);

      Canvas canvas = new Canvas();
      canvas.setIgnoreRepaint(true);
      canvas.setSize(dim);

      final Frame window = new Frame();
      window.setIgnoreRepaint(true);
      window.setTitle(windowTitle);
      window.setFocusable(true);
      window.addWindowListener(new WindowAdapter() {
         @Override
         public void windowClosing(WindowEvent e) {
            window.dispose();
         }
      });
      window.add(canvas);
      window.setResizable(false);
      window.pack();
      window.setLocationRelativeTo(null);
      window.setVisible(true);

      canvas.createBufferStrategy(2);
      final BufferStrategy buffer = canvas.getBufferStrategy();

      long secondStarted = System.nanoTime();
      int framecounter = 0;

      long interval = 1_000_000_000 / this.getFrameFrequency();
      long nextFrame = System.nanoTime();

      while (window.isVisible()) {
         image = frameImageQueue.take();
         if (image == null) {
            System.out.println("Image Queue: EOF");
            break;
         }

         this.tickAudio();

         if (interval > 0) {
            while (System.nanoTime() < nextFrame) {
               HighLevel.sleep(1);
            }
            nextFrame += interval;
         }

         Graphics g;
         try {
            g = buffer.getDrawGraphics();
         } catch (IllegalStateException exc) {
            break;
         }
         g.drawImage(image, 0, 0, null);
         g.dispose();
         image.flush();
         buffer.show();

         framecounter++;
         if (System.nanoTime() > secondStarted + 1000_000_000L) {
            window.setTitle(windowTitle + " - " + framecounter + "fps");
            framecounter = 0;
            secondStarted += 1000_000_000L;
         }
      }

      window.dispose();

      this.stop();
   }

   public abstract void stop();
}


1   2   3   4   5   6   7   8   9   10   11   12   13   14   15   16   17   18   19   20   21   22   23   24   25   26   27   28   29   30   31   32   33   34   35   36   37   38   39   40   41   42   43   44   45   46   47   48   49   50   51   52   53   54   55   56   57   58   59   60   61   62   63   64   65   66   67   68   69   70   71   72  
package main.vlc;

import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;

import craterstudio.data.ByteList;
import craterstudio.io.Streams;

public class MjpegVideoPlayback extends AbstractVideoPlayback {
   private final InputStream videoStream;
   private final OpenALStream audioStream;
   private final int hz;

   public MjpegVideoPlayback(InputStream mjpegFile, InputStream wavFile, int hz) throws IOException {
      this.hz = hz;
      this.videoStream = new BufferedInputStream(mjpegFile);
      this.audioStream = new OpenALStream(new WavHeader(new DataInputStream(new BufferedInputStream(wavFile))));
   }

   @Override
   public int getFrameFrequency() {
      return this.hz;
   }

   @Override
   public void tickAudio() {
      this.audioStream.tick();
   }

   @Override
   void runReadLoop() {
      ByteList jpeg = new ByteList();

      try {
         while (true) {
            int prev = 0;
            while (true) {
               int got = videoStream.read();
               if (got == -1) {
                  if (jpeg.size() == 0) {
                     this.frameDataQueue.put(null);
                     return;
                  }
                  throw new EOFException();
               }
               jpeg.add((byte) got);

               // what are the odds?
               if (prev == 0xff && got == 0xd9) { // EOI / EndOfImage
                  byte[] data = jpeg.toArray();
                  jpeg.clear();

                  this.frameDataQueue.put(data);
               }

               prev = got;
            }
         }
      } catch (IOException exc) {
         throw new IllegalStateException();
      }
   }

   @Override
   public void stop() {
      Streams.safeClose(videoStream);
      Streams.safeClose(audioStream);
   }
}


1   2   3   4   5   6   7   8   9   10   11   12   13   14   15   16   17   18   19   20   21   22   23   24  
package main.vlc;

import java.io.File;
import java.io.InputStream;

import org.lwjgl.openal.AL;

class VideoPlayback {
   public static void main(String[] args) throws Exception {

      final File movieFile = new File("D:/something.mp4");

      InputStream videoStream = FFmpeg.extractVideoAsMJPEG(movieFile);
      InputStream audioStream = FFmpeg.extractAudioAsWAV(movieFile);

      AL.create();

      int frameRate = 25;

      AbstractVideoPlayback playback = new MjpegVideoPlayback(videoStream, audioStream, frameRate);
      playback.startVideo("My First Video Playback");
   }

}


1   2   3   4   5   6   7   8   9   10   11   12   13   14   15   16   17   18   19   20   21   22   23   24   25   26   27   28   29   30   31   32   33   34   35   36   37   38   39   40   41   42   43   44   45   46   47   48   49   50   51   52   53   54   55   56   57   58   59   60   61   62   63   64   65   66   67   68   69   70   71   72   73   74   75   76   77   78   79   80   81   82  
package main.vlc;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;

import craterstudio.io.Streams;
import craterstudio.streams.NullOutputStream;

public class FFmpeg {
   public static String FFMPEG_PATH = "C:/mounts/workdisk/apps/ffmpeg/ffmpeg-20120810-git-633b90c-win64-static/bin/ffmpeg.exe";
   public static boolean FFMPEG_VERBOSE = false;
   public static String JPEG_QUALITY = "1";

   public static void extractVideoAsMJPEG(File srcMovieFile, File dstMjpegFile) throws IOException {
      await(new ProcessBuilder().command(//
         FFMPEG_PATH, //
         "-y", //
         "-i", srcMovieFile.getAbsolutePath(), //
         "-qscale", JPEG_QUALITY, //
         dstMjpegFile.getAbsolutePath() //
         ));
   }

   public static InputStream extractVideoAsMJPEG(File srcMovieFile) throws IOException {
      return streamData(new ProcessBuilder().command(//
         FFMPEG_PATH, //
         "-y", //
         "-i", srcMovieFile.getAbsolutePath(), //
         "-qscale", JPEG_QUALITY, //
         "-f", "mjpeg", //
         "-"//
      ));
   }

   //

   public static void extractAudioAsWAV(File srcMovieFile, File dstWavFile) throws IOException {
      await(new ProcessBuilder().command(//
         FFMPEG_PATH, //
         "-y", //
         "-i", srcMovieFile.getAbsolutePath(), //
         "-acodec", "pcm_s16le", //
         "-ac", "2", //
         "-ar", "44100", //
         "-f", "wav", //
         dstWavFile.getAbsolutePath() //
         ));
   }

   public static InputStream extractAudioAsWAV(File srcMovieFile) throws IOException {
      return streamData(new ProcessBuilder().command(//
         FFMPEG_PATH, //
         "-y", //
         "-i", srcMovieFile.getAbsolutePath(), //
         "-acodec", "pcm_s16le", //
         "-ac", "2", //
         "-ar", "44100", //
         "-f", "wav", //
         "-" //
      ));
   }

   //

   private static void await(ProcessBuilder pb) throws IOException {
      Process process = pb.start();
      Streams.asynchronousTransfer(process.getInputStream(), System.out, true, false);
      Streams.asynchronousTransfer(process.getErrorStream(), System.err, true, false);
      try {
         process.waitFor();
      } catch (InterruptedException exc) {
         throw new IllegalStateException(exc);
      }
   }

   private static InputStream streamData(ProcessBuilder pb) throws IOException {
      Process process = pb.start();
      Streams.asynchronousTransfer(process.getErrorStream(), FFMPEG_VERBOSE ? System.err : new NullOutputStream(), true, false);
      return process.getInputStream();
   }
}


1   2   3   4   5   6   7   8   9   10   11   12   13   14   15   16   17   18   19   20   21   22   23   24   25   26   27   28   29   30   31   32   33   34   35   36   37   38   39   40   41   42   43   44   45   46   47   48   49   50   51   52   53   54   55   56   57   58   59   60   61   62   63   64   65   66   67   68   69   70   71   72   73   74   75   76   77   78   79   80   81   82   83   84   85   86   87   88   89   90   91   92   93   94   95   96   97   98   99   100   101   102   103   104  
package main.vlc;

import java.io.Closeable;
import java.io.DataInput;
import java.io.IOException;

public class WavHeader implements Closeable {
   int audioFormat;
   int numChannels;
   int sampleRate;
   int byteRate;
   int blockAlign;
   int bytesPerSample;

   final DataInput input;
   int sampleCount;

   public WavHeader(DataInput input) throws IOException {
      this.input = input;

      while (true) {
         String chunkName = readString(input, 4);
         int chunkSize = swap32(input.readInt());

         if (chunkName.equals("RIFF")) {
            if (!"WAVE".equals(readString(input, 4))) {
               throw new IllegalStateException();
            }
         } else if (chunkName.equals("fmt ")) {
            this.audioFormat = swap16(input.readUnsignedShort());
            this.numChannels = swap16(input.readUnsignedShort());
            this.sampleRate = swap32(input.readInt());
            this.byteRate = swap32(input.readInt());
            this.blockAlign = swap16(input.readUnsignedShort());
            this.bytesPerSample = swap16(input.readUnsignedShort()) / 8;

            int off = 16;
            while (off++ < chunkSize)
               input.readByte();
         } else if (chunkName.equals("data")) {
            this.sampleCount = chunkSize / this.bytesPerSample / this.numChannels;
            break;
         } else

         {
            int off = 0;
            while (off++ < chunkSize)
               input.readByte();
         }
      }

      if (this.audioFormat != 1) {
         if (input instanceof Closeable)
            ((Closeable) input).close();
         throw new IllegalStateException("can only parse uncompressed wav files: " + audioFormat);
      }
   }

   public int bytesPerSample() {
      return this.bytesPerSample;
   }

   public int numChannels() {
      return this.numChannels;
   }

   public int sampleRate() {
      return this.sampleRate;
   }

   public int sampleCount() {
      return this.sampleCount;
   }

   public void close() throws IOException {
      if (input instanceof Closeable)
         ((Closeable) input).close();
   }

   //

   private static String readString(DataInput raf, int len) throws IOException {
      char[] cs = new char[len];
      for (int i = 0; i < len; i++)
         cs[i] = (char) (raf.readByte() & 0xFF);
      return new String(cs);
   }

   private static int swap16(int i) {
      int b = 0;
      b |= ((i >> 8) & 0xFF) << 0;
      b |= ((i >> 0) & 0xFF) << 8;
      return b;
   }

   private static int swap32(int i) {
      int b = 0;
      b |= ((i >> 24) & 0xFF) << 0;
      b |= ((i >> 16) & 0xFF) << 8;
      b |= ((i >> 8) & 0xFF) << 16;
      b |= ((i >> 0) & 0xFF) << 24;
      return b;
   }
}


1   2   3   4   5   6   7   8   9   10   11   12   13   14   15   16   17   18   19   20   21   22   23   24   25   26   27   28   29   30   31   32   33   34   35   36   37   38   39   40   41   42   43   44   45   46   47   48   49   50   51   52   53   54   55   56   57   58   59   60   61   62   63   64   65   66   67   68   69   70   71   72   73   74   75   76   77   78   79  
package main.vlc;

import static org.lwjgl.openal.AL10.*;

import java.io.Closeable;
import java.io.DataInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.LinkedList;

class OpenALStream implements Closeable {
   final LinkedList<Integer> enqueuedBufferQueue = new LinkedList<Integer>();
   final ByteBuffer bb;
   final byte[] tmp;
   final WavHeader wavHeaver;
   final int source;

   public OpenALStream(final WavHeader wavHeaver) {
      this.wavHeaver = wavHeaver;

      this.tmp = new byte[(wavHeaver.sampleRate/4) * (2 + 2)];
      this.bb = ByteBuffer.allocateDirect(this.tmp.length);

      this.source = alGenSources();
   }

   int lastBuffersProcessed = 0;
   boolean inited = false;

   public void tick() {
      if (!inited) {
         inited = true;

         for (int i = 0; i < 8; i++) {
            this.loadNextSamples();
         }

         alSourcePlay(source);
      }

      int currentBuffersProcessed = alGetSourcei(source, AL_BUFFERS_PROCESSED);
      int toDiscard = currentBuffersProcessed - lastBuffersProcessed;
      lastBuffersProcessed = currentBuffersProcessed;

      if (toDiscard == 0) {
         return;
      }

      for (int i = 0; i < toDiscard; i++) {
         int buffer = enqueuedBufferQueue.removeFirst().intValue();
         alDeleteBuffers(buffer);

         this.loadNextSamples();
      }
   }

   public void loadNextSamples() {
      try {
         ((DataInputStream) wavHeaver.input).readFully(tmp);

         bb.clear();
         bb.put(tmp);
         bb.flip();

         int buffer = alGenBuffers();
         {
            alBufferData(buffer, AL_FORMAT_STEREO16, bb, wavHeaver.sampleRate);
            alSourceQueueBuffers(source, buffer);
         }
         enqueuedBufferQueue.addLast(Integer.valueOf(buffer));
      } catch (IOException exc) {
         exc.printStackTrace();
      }
   }

   public void close() throws IOException {
      this.wavHeaver.close();
   }
}





Dump your java code here :



Special syntax:
  • To highlight a line (yellow background), prefix it with '@@'
  • To indicate that a line should be removed (red background), prefix it with '-'
  • To indicate that a line should be added (green background), prefix it with '+'
  • To post multiple snippets, seperate them by '~~~~'
  EOF
 

Add your game by posting it in the WIP section,
or publish it in Showcase.

The first screenshot will be displayed as a thumbnail.

CogWheelz (18 views)
2014-07-31 11:08:39

Riven (27 views)
2014-07-30 08:09:19

Riven (16 views)
2014-07-30 08:08:52

Dwinin (14 views)
2014-07-30 00:59:34

E.R. Fleming (35 views)
2014-07-29 17:07:13

E.R. Fleming (13 views)
2014-07-29 17:06:25

pw (44 views)
2014-07-24 15:59:36

Riven (45 views)
2014-07-24 11:16:32

Riven (30 views)
2014-07-24 11:07:15

Riven (31 views)
2014-07-24 10:56:16
List of Learning Resources
by SilverTiger
2014-08-01 08:29:50

List of Learning Resources
by SilverTiger
2014-08-01 08:26:06

List of Learning Resources
by SilverTiger
2014-08-01 03:54:12

HotSpot Options
by dleskov
2014-07-08 17:59:08

Java and Game Development Tutorials
by SwordsMiner
2014-06-14 14:58:24

Java and Game Development Tutorials
by SwordsMiner
2014-06-14 14:47:22

How do I start Java Game Development?
by ra4king
2014-05-18 01:13:37

HotSpot Options
by Roquen
2014-05-15 23:59:54
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!