Unable to encode series of JPEG images to MPEG video - java

I need to convert JPEG images to MPEG video and to be able to easily set the duration that each frame displayed.
I have tried JMF, Xuggler, & JCodec but all have their problems.
I will appreciate any solution that is well explained for either JMF , Xuggler, JCode, or even JavaCV(Have not tried this).
Below are my coding attempts.
My testing menu & main, used to test either Xuggler approach or JCodec:
package com.conuretech.video_assembler;
import com.xuggle.xuggler.IContainerFormat;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
*
* #author ANaim
*/
public class TestVideo {
public static void main (String [] args)
{
if (args[0].equalsIgnoreCase("1"))
{
System.out.println("Testing Xuggler ...");
Iterator<IContainerFormat> iterator = IContainerFormat.getInstalledOutputFormats().iterator();
while (iterator.hasNext())
{
System.out.println(iterator.next().toString());
}
System.out.println("Testing xuggler...");
//C:\Users\Public\Pictures\Sample_Pictures_2\1.jpg
XugglerJpegImagesToMpegVideo newjpegImagesToMpegVideo = new XugglerJpegImagesToMpegVideo();
newjpegImagesToMpegVideo.setFrameRate(25);
newjpegImagesToMpegVideo.setOutputFilenamePath("C:/Users/Public/Pictures/Sample_Pictures_2/video.mpg");
List<String> jpegImages = new ArrayList<String>();
jpegImages.add("C:/Users/Public/Pictures/Sample_Pictures_2/1.jpg");
jpegImages.add("C:/Users/Public/Pictures/Sample_Pictures_2/2.jpg");
jpegImages.add("C:/Users/Public/Pictures/Sample_Pictures_2/3.jpg");
jpegImages.add("C:/Users/Public/Pictures/Sample_Pictures_2/4.jpg");
jpegImages.add("C:/Users/Public/Pictures/Sample_Pictures_2/5.jpg");
jpegImages.add("C:/Users/Public/Pictures/Sample_Pictures_2/6.jpg");
jpegImages.add("C:/Users/Public/Pictures/Sample_Pictures_2/7.jpg");
jpegImages.add("C:/Users/Public/Pictures/Sample_Pictures_2/8.jpg");
newjpegImagesToMpegVideo.setJpegFilePathList(jpegImages);
newjpegImagesToMpegVideo.convertJpegFramesToMpegVideo();
}
else if (args[0].equalsIgnoreCase("2"))
{
System.out.println("Testing JCodec...");
jCodecJpegImagesToMpegVideo newJCodecJpegImagesToMpegVideo = new jCodecJpegImagesToMpegVideo();
List<String> jpegImages = new ArrayList<String>();
jpegImages.add("C:/Users/Public/Pictures/Sample_Pictures_2/1.jpg");
jpegImages.add("C:/Users/Public/Pictures/Sample_Pictures_2/2.jpg");
jpegImages.add("C:/Users/Public/Pictures/Sample_Pictures_2/3.jpg");
jpegImages.add("C:/Users/Public/Pictures/Sample_Pictures_2/4.jpg");
jpegImages.add("C:/Users/Public/Pictures/Sample_Pictures_2/5.jpg");
jpegImages.add("C:/Users/Public/Pictures/Sample_Pictures_2/6.jpg");
jpegImages.add("C:/Users/Public/Pictures/Sample_Pictures_2/7.jpg");
jpegImages.add("C:/Users/Public/Pictures/Sample_Pictures_2/8.jpg");
newJCodecJpegImagesToMpegVideo.setJpegFilePathList(jpegImages);
newJCodecJpegImagesToMpegVideo.convertJpegFramesToMpegVideo();
}
else
{
}
System.exit(0);
}
}
My pom.xml (includes Xuggler & JCodec dependencies):
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.conuretech</groupId>
<artifactId>Video_Assembler</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Video_Assembler</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!--<mainClass>com.conuretech.video_assembler.TestVideo</mainClass>-->
<mainClass>com.conuretech.video_assembler.MainApp</mainClass>
</properties>
<organization>
<!-- Used as the 'Vendor' for JNLP generation -->
<name>conuretech</name>
</organization>
<repositories>
<repository>
<id>xuggle repo</id>
<url>http://xuggle.googlecode.com/svn/trunk/repo/share/java/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.jcodec</groupId>
<artifactId>jcodec</artifactId>
<version>0.1.9</version>
</dependency>
<dependency>
<groupId>xuggle</groupId>
<artifactId>xuggle-xuggler</artifactId>
<version>5.4</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.6.4</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>commons-cli</groupId>
<artifactId>commons-cli</artifactId>
<version>1.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.0.0</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.0.0</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>xuggle</groupId>
<artifactId>xuggle-utils</artifactId>
<version>1.22</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<id>unpack-dependencies</id>
<phase>package</phase>
<goals>
<goal>unpack-dependencies</goal>
</goals>
<configuration>
<excludeScope>system</excludeScope>
<excludeGroupIds>junit,org.mockito,org.hamcrest</excludeGroupIds>
<outputDirectory>${project.build.directory}/classes</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<executions>
<execution>
<id>unpack-dependencies</id>
<phase>package</phase>
<goals>
<goal>exec</goal>
</goals>
<configuration>
<executable>${java.home}/../bin/javafxpackager</executable>
<arguments>
<argument>-createjar</argument>
<argument>-nocss2bin</argument>
<argument>-appclass</argument>
<argument>${mainClass}</argument>
<argument>-srcdir</argument>
<argument>${project.build.directory}/classes</argument>
<argument>-outdir</argument>
<argument>${project.build.directory}</argument>
<argument>-outfile</argument>
<argument>${project.build.finalName}.jar</argument>
</arguments>
</configuration>
</execution>
<execution>
<id>default-cli</id>
<goals>
<goal>exec</goal>
</goals>
<configuration>
<executable>${java.home}/bin/java</executable>
<commandlineArgs>${runfx.args}</commandlineArgs>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
<compilerArguments>
<bootclasspath>${sun.boot.class.path}${path.separator}${java.home}/lib/jfxrt.jar</bootclasspath>
</compilerArguments>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.16</version>
<configuration>
<additionalClasspathElements>
<additionalClasspathElement>${java.home}/lib/jfxrt.jar</additionalClasspathElement>
</additionalClasspathElements>
</configuration>
</plugin>
</plugins>
</build>
</project>
JMF Attempt – According their data format site , they don’t support MPEG “write” or encoding only “read” decoding, see their formats (http://www.oracle.com/technetwork/java/javase/formats-138492.html).
Xuggler Attempt (XugglerJpegImagesToMpegVideo.java) –
package com.conuretech.video_assembler;
import com.xuggle.mediatool.IMediaWriter;
import com.xuggle.mediatool.ToolFactory;
import com.xuggle.xuggler.IContainer;
import com.xuggle.xuggler.IContainerFormat;
import java.util.ArrayList;
import java.util.List;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
/**
*
* #author ANaim
*/
public class XugglerJpegImagesToMpegVideo {
//how many frames will be displayed per minute
private int frameRate = 1;
//total number of frames to be assembled into a video file
private int numberOfFrames = 0;
//path to output mpeg video
private String outputFilenamePath = "";
//list of JPEG pictures to be converted
private List<String> jpegFilePathList = new ArrayList<String>();
private List<BufferedImage> jpegFileList = new ArrayList<BufferedImage>();
public void convertJpegFramesToMpegVideo() {
System.out.println("convertJpegFramesToMpegVideo");
// BufferedImage to store JPEG data from file
BufferedImage img = null;
IContainer container = IContainer.make();
IMediaWriter writer = null;
long startTime = 0;
//ISSUE - container.open() fails to open
if (container.open(getOutputFilenamePath(), IContainer.Type.WRITE, null) > 0)
{
writer = ToolFactory.makeWriter(getOutputFilenamePath(),container);
this.setNumberOfFrames(getJpegFilePathList().size());
}
else
{
throw new RuntimeException("class jpegImagesToMpegVideo,convertJpegFramesToMpegVideo(), failed to open");
}
File imgFile = null;
//loop to load data from paths to BufferedImage objects
for (int i = 0; i < jpegFilePathList.size(); i++)
{
imgFile = new File(getJpegFilePathList().get(i));
if (imgFile.exists())
{
//System.out.println("convertJpegFramesToMpegVideo, file path: "+imgFile.getPath()+" exists");
try
{
img = ImageIO.read(imgFile);
jpegFileList.add(img);
}
catch (IOException e) {
e.printStackTrace();
}
}
else
{
System.out.println("convertJpegFramesToMpegVideo, file path: "+imgFile.getPath()+" does not exist!");
}
}//end for to load path to images
long nextEncodeTime = 0L;
startTime = System.nanoTime();
//for loop to encode each BufferedImage
for (int i = 0; i < jpegFileList.size(); i++) {
System.out.println("convertJpegFramesToMpegVideo encode counter: "+i);
img = jpegFileList.get(i);
nextEncodeTime = System.nanoTime() - startTime;
//encode
writer.encodeVideo(0, img,nextEncodeTime, TimeUnit.NANOSECONDS);
try {
/*Duration of each image - sleep 1000 millisecs (1 sec)
in order to shift outcome of the next nextEncodeTime = System.nanoTime() - startTime calcultation
by 1 second in order to have each frame displayed for 1 sec*/
Thread.sleep(1000);
} catch (InterruptedException ex) {
Logger.getLogger(XugglerJpegImagesToMpegVideo.class.getName()).log(Level.SEVERE, null, ex);
}
}//end loop
// after encoding all BufferedImages close
writer.close();
}//end
public int getFrameRate() {
return frameRate;
}
public void setFrameRate(int frameRate) {
this.frameRate = frameRate;
}
public int getNumberOfFrames() {
return numberOfFrames;
}
public void setNumberOfFrames(int numberOfFrames) {
this.numberOfFrames = numberOfFrames;
}
public String getOutputFilenamePath() {
return outputFilenamePath;
}
public void setOutputFilenamePath(String outputFilenamePath) {
this.outputFilenamePath = outputFilenamePath;
}
public List<String> getJpegFilePathList() {
return jpegFilePathList;
}
public void setJpegFilePathList(List<String> jpegFilePathList) {
this.jpegFilePathList = jpegFilePathList;
}
}
Issue-
The container fails to open, here is the exact snippet:
//ISSUE - container.open() fails to open
if (container.open(getOutputFilenamePath(), IContainer.Type.WRITE, null) > 0)
{
writer = ToolFactory.makeWriter(getOutputFilenamePath(),container);
this.setNumberOfFrames(getJpegFilePathList().size());
}
JCodec Attempt (jCodecJpegImagesToMpegVideo.java):
With jCodec I had 2 approaches first using the built in org.jcodec.api.SequenceEncoder and later based on other posts online creating my own SequenceEncoder class called MySequenceEncoder, because the org.jcodec.api.SequenceEncoder did not have any methods to set duration on each frame.
package com.conuretech.video_assembler;
import java.awt.image.BufferedImage;
import java.awt.image.DataBuffer;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.imageio.ImageIO;
import org.jcodec.api.SequenceEncoder;
import org.jcodec.codecs.h264.H264Encoder;
import org.jcodec.common.model.ColorSpace;
import org.jcodec.common.model.Picture;
/**
*
* #author ANaim
*/
public class jCodecJpegImagesToMpegVideo {
//list of JPEG pictures to be converted
private List<String> jpegFilePathList = new ArrayList<String>();
private List<BufferedImage> jpegFileList = new ArrayList<BufferedImage>();
public void convertJpegFramesToMpegVideo() {
System.out.println("convertJpegFramesToMpegVideo");
//TODO: make dimensions dynanmic
BufferedImage img = null;
File imgFile = null;
for (int i = 0; i < jpegFilePathList.size(); i++)
{
imgFile = new File(getJpegFilePathList().get(i));
if (imgFile.exists())
{
//System.out.println("convertJpegFramesToMpegVideo, file path: "+imgFile.getPath()+" exists");
try
{
img = ImageIO.read(imgFile);
jpegFileList.add(img);
}
catch (IOException e) {
e.printStackTrace();
}
}
else
{
System.out.println("convertJpegFramesToMpegVideo, file path: "+imgFile.getPath()+" does not exist!");
}
}//end for to load path to images
File outVideoFile = new File("C:/Users/Public/Pictures/Sample_Pictures_2/video.mp4");
//Class that encodes images to a video
try
{
/*Attempt # 1 using org.jcodec.api.SequenceEncoder - SequenceEncoder class does not have method to specify duration,fps,etc..
SequenceEncoder newSequenceEncoder = new SequenceEncoder(outVideoFile);*/
/*Attempt # 2 - MySequenceEncoder is based on JCodec SequenceEncoder class src from GitHub,
were on can have finer access regarding duration & fps via " outTrack.addFrame(new MP4Packet(result,25,1,1,frameNo,true,null,1,0));"
however there is no official documentation describing how to set outTrack.addFrame(new MP4Packet(result,25,1,1,frameNo,true,null,1,0));*/
MySequenceEncoder newSequenceEncoder = new MySequenceEncoder(outVideoFile);
//H264 (aka mpeg) encoder
H264Encoder encoder = new H264Encoder();
//JCode class that holds media data before final processing
Picture toEncode = null;
//for loop to convert images to mpeg video
System.out.println("SupportedColorSpaces: "+encoder.getSupportedColorSpaces()[0]);
for (int i=0; i<jpegFileList.size(); i++)
{
img = jpegFileList.get(i);
toEncode = makeFrame(img, encoder.getSupportedColorSpaces()[0]);
//encode
newSequenceEncoder.encodeNativeFrame(toEncode);
}//end loop
//end encoding close sequence
newSequenceEncoder.finish();
}
catch (IOException exc)
{
exc.printStackTrace();
}
}//end
//I took this code from Stackoverflow because JCodecs AWTUtil was deprecated and this method converts BufferedImage to Picture class
private Picture makeFrame(BufferedImage bi, ColorSpace cs)
{
DataBuffer imgdata = bi.getRaster().getDataBuffer();
int[] ypix = new int[imgdata.getSize()];
int[] upix = new int[ imgdata.getSize() >> 2 ];
int[] vpix = new int[ imgdata.getSize() >> 2 ];
int ipx = 0, uvoff = 0;
for (int h = 0; h < bi.getHeight(); h++) {
for (int w = 0; w < bi.getWidth(); w++) {
int elem = imgdata.getElem(ipx);
int r = 0x0ff & (elem >>> 16);
int g = 0x0ff & (elem >>> 8);
int b = 0x0ff & elem;
ypix[ipx] = ((66 * r + 129 * g + 25 * b) >> 8) + 16;
if ((0 != w % 2) && (0 != h % 2)) {
upix[uvoff] = (( -38 * r + -74 * g + 112 * b) >> 8) + 128;
vpix[uvoff] = (( 112 * r + -94 * g + -18 * b) >> 8) + 128;
uvoff++;
}
ipx++;
}
}
int[][] pix = { ypix, upix, vpix, null };
return new Picture(bi.getWidth(), bi.getHeight(), pix, cs);
}
public List<String> getJpegFilePathList() {
return jpegFilePathList;
}
public void setJpegFilePathList(List<String> jpegFilePathList) {
this.jpegFilePathList = jpegFilePathList;
}
public List<BufferedImage> getJpegFileList() {
return jpegFileList;
}
public void setJpegFileList(List<BufferedImage> jpegFileList) {
this.jpegFileList = jpegFileList;
}
}//end class
Here is my sequence encoder (MySequenceEncoder.java) , I took the source from JCodec's github:
package com.conuretech.video_assembler;
import org.jcodec.api.SequenceEncoder;
import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import org.jcodec.codecs.h264.H264Encoder;
import org.jcodec.codecs.h264.H264Utils;
import org.jcodec.common.NIOUtils;
import org.jcodec.common.SeekableByteChannel;
import org.jcodec.common.model.ColorSpace;
import org.jcodec.common.model.Picture;
import org.jcodec.containers.mp4.Brand;
import org.jcodec.containers.mp4.MP4Packet;
import org.jcodec.containers.mp4.TrackType;
import org.jcodec.containers.mp4.muxer.FramesMP4MuxerTrack;
import org.jcodec.containers.mp4.muxer.MP4Muxer;
import org.jcodec.scale.ColorUtil;
import org.jcodec.scale.Transform;
public class MySequenceEncoder {
/**
* This class is part of JCodec ( www.jcodec.org ) This software is distributed
* under FreeBSD License
*
* #author The JCodec project
*
*/
private SeekableByteChannel ch;
private Picture toEncode;
private Transform transform;
private H264Encoder encoder;
private ArrayList<ByteBuffer> spsList;
private ArrayList<ByteBuffer> ppsList;
private FramesMP4MuxerTrack outTrack;
private ByteBuffer _out;
private int frameNo;
private MP4Muxer muxer;
public MySequenceEncoder(File out) throws IOException {
this.ch = NIOUtils.writableFileChannel(out);
// Muxer that will store the encoded frames
muxer = new MP4Muxer(ch, Brand.MP4);
// Add video track to muxer
outTrack = muxer.addTrack(TrackType.VIDEO, 25);
// Allocate a buffer big enough to hold output frames
_out = ByteBuffer.allocate(1920 * 1080 * 6);
// Create an instance of encoder
encoder = new H264Encoder();
// Transform to convert between RGB and YUV
transform = ColorUtil.getTransform(ColorSpace.RGB, encoder.getSupportedColorSpaces()[0]);
// Encoder extra data ( SPS, PPS ) to be stored in a special place of
// MP4
spsList = new ArrayList<ByteBuffer>();
ppsList = new ArrayList<ByteBuffer>();
}
public void encodeNativeFrame(Picture pic) throws IOException {
if (toEncode == null) {
toEncode = Picture.create(pic.getWidth(), pic.getHeight(), encoder.getSupportedColorSpaces()[0]);
}
// Perform conversion
transform.transform(pic, toEncode);
// Encode image into H.264 frame, the result is stored in '_out' buffer
_out.clear();
ByteBuffer result = encoder.encodeFrame(toEncode, _out);
// Based on the frame above form correct MP4 packet
spsList.clear();
ppsList.clear();
H264Utils.wipePS(result, spsList, ppsList);
H264Utils.encodeMOVPacket(result);
//ISSUE - Im not sure what values to supply to MP4Packet() in order to control the duration of each frame to 1 sec
outTrack.addFrame(new MP4Packet(result,25,1,1,frameNo,true,null,1,0));
frameNo++;
}
public void finish() throws IOException {
// Push saved SPS/PPS to a special storage in MP4
outTrack.addSampleEntry(H264Utils.createMOVSampleEntry(spsList, ppsList, 4));
// Write MP4 header and finalize recording
muxer.writeHeader();
NIOUtils.closeQuietly(ch);
}
}//end class
Issue - Whether using SequenceEncoder.java or MySequenceEncoder.java the video that gets created doesnt play, there are no errors either, the video opens but nothing is displayed.
I'm also unable to figure what are correct parameters to pass into:
outTrack.addFrame(new MP4Packet(result,25,1,1,frameNo,true,null,1,0));
Again a working JMF, Xuggler, JCodec , or JavaCV solution , with full instructions & dependency information will be greatly appreciated.
Thank you all in advance.

I finally got a working solution that converts JPEG images into MPEG extension ".mp4" video using the Xuggler library:
Here is my modified "XugglerJpegImagesToMpegVideo.java" :
package com.conuretech.video_assembler;
import com.xuggle.mediatool.IMediaWriter;
import com.xuggle.mediatool.ToolFactory;
import com.xuggle.xuggler.IContainer;
import java.util.ArrayList;
import java.util.List;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import javax.imageio.ImageIO;
import com.xuggle.xuggler.ICodec;
import com.xuggle.xuggler.IRational;
/**
*
* #author Aryan Naim
* This class converts JPEG images to MPEG (.mp4) extension video using Xuggler library
*/
public class XugglerJpegImagesToMpegVideo {
//fps = how many frames will be displayed per sec, default 24
private int frameRate = 24;
//number of millisecs each frame will be displayed for the viewer , default 1000 millisecs
private long durationPerFrame = 1000;
//path to output mpeg video
private String outputFilenamePath = "";
//list of JPEG pictures to be converted
private List<String> jpegFilePathList = new ArrayList<String>();
//list of actual images in memory to be iterated through & encoded by Xuggler
private List<BufferedImage> jpegFileList = new ArrayList<BufferedImage>();
/* VERY IMPORTANT regarding setDurationPerFrame(), I noticed that fpr 24 fps ,
the expected duration fell short 15% or 150 millisec per 1 second,
therefore I adjusted this by adding 15% to the user specified duration,
For example 3000 millisec duration will be adjusted to 3450 millisecs.
This adjustment was even more severe for lower fps*/
public void setDurationPerFrame(long durationPerFrame) {
this.durationPerFrame = new Double(Math.ceil(durationPerFrame * 1.15)).longValue();
}
public long getDurationPerFrame() {
return durationPerFrame;
}
/*
Actual method that converts JPEG images to MPEG (.mp4) extension video using Xuggler library
*/
public void convertJpegFramesToMpegVideo() {
System.out.println("convertJpegFramesToMpegVideo, start...");
// BufferedImage to store JPEG data from file
BufferedImage img = null;
IContainer container = IContainer.make();
IMediaWriter writer = null;
long nextEncodeTime = getDurationPerFrame();
writer = ToolFactory.makeWriter(getOutputFilenamePath(), container);
//the framerate is set at 24 fps , could be adjusted
writer.addVideoStream(0, 0, ICodec.ID.CODEC_ID_MPEG4,IRational.make(frameRate),1024,768);
File imgFile = null;
//loop to load data from paths to BufferedImage objects
for (int i = 0; i < jpegFilePathList.size(); i++) {
imgFile = new File(getJpegFilePathList().get(i));
if (imgFile.exists()) {
try {
img = ImageIO.read(imgFile);
jpegFileList.add(img);
} catch (IOException e) {
e.printStackTrace();
}
} else {
System.out.println("convertJpegFramesToMpegVideo, file path: " + imgFile.getPath() + " does not exist!");
}
}//end for to load path to images
//for loop to encode each BufferedImage
for (int i = 0; i <jpegFileList.size(); i++) {
System.out.println("convertJpegFramesToMpegVideo encoded frame counter: " + i);
img = jpegFileList.get(i);
writer.encodeVideo(0, img, nextEncodeTime, TimeUnit.MILLISECONDS);
nextEncodeTime = nextEncodeTime + getDurationPerFrame();
}//end loop
// after encoding all BufferedImages close
writer.close();
System.out.println("convertJpegFramesToMpegVideo, end!");
}//end
public int getFrameRate() {
return frameRate;
}
public void setFrameRate(int frameRate) {
this.frameRate = frameRate;
}
public String getOutputFilenamePath() {
return outputFilenamePath;
}
public void setOutputFilenamePath(String outputFilenamePath) {
this.outputFilenamePath = outputFilenamePath;
}
public List<String> getJpegFilePathList() {
return jpegFilePathList;
}
public void setJpegFilePathList(List<String> jpegFilePathList) {
this.jpegFilePathList = jpegFilePathList;
}
public List<BufferedImage> getJpegFileList() {
return jpegFileList;
}
public void setJpegFileList(List<BufferedImage> jpegFileList) {
this.jpegFileList = jpegFileList;
}
}//end class
Here is the main class that instantiates the XugglerJpegImagesToMpegVideo.java and set the parameters such JPEG file paths, fps, and frame duration:
package com.conuretech.video_assembler;
import com.xuggle.xuggler.IContainerFormat;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
*
* #author ANaim
*/
public class TestVideo {
public static void main (String [] args)
{
if (args[0].equalsIgnoreCase("1"))
{
System.out.println("Testing xuggler...");
XugglerJpegImagesToMpegVideo newjpegImagesToMpegVideo = new XugglerJpegImagesToMpegVideo();
newjpegImagesToMpegVideo.setFrameRate(24);
//duration in millisecs, for example 2 secs will be 2000
newjpegImagesToMpegVideo.setDurationPerFrame(2000);
newjpegImagesToMpegVideo.setOutputFilenamePath("C:/Users/Public/Pictures/Sample_Pictures_2/video.mp4");
List<String> jpegImages = new ArrayList<String>();
jpegImages.add("C:/Users/Public/Pictures/Sample_Pictures_2/1.jpg");
jpegImages.add("C:/Users/Public/Pictures/Sample_Pictures_2/2.jpg");
jpegImages.add("C:/Users/Public/Pictures/Sample_Pictures_2/3.jpg");
jpegImages.add("C:/Users/Public/Pictures/Sample_Pictures_2/4.jpg");
jpegImages.add("C:/Users/Public/Pictures/Sample_Pictures_2/5.jpg");
jpegImages.add("C:/Users/Public/Pictures/Sample_Pictures_2/6.jpg");
jpegImages.add("C:/Users/Public/Pictures/Sample_Pictures_2/7.jpg");
jpegImages.add("C:/Users/Public/Pictures/Sample_Pictures_2/8.jpg");
newjpegImagesToMpegVideo.setJpegFilePathList(jpegImages);
newjpegImagesToMpegVideo.convertJpegFramesToMpegVideo();
}
else
{
}
System.exit(0);
}
}//end main
This created a 16 second MPEG video with 2 secs duration for each frame.
Thats all folks!

Related

AWS Transcribe S3 .wav file to text

I am trying to use aws Transcribe to convert a wav file to text. I have uploaded a wav file to S3, which is located here and it has public read/write permissions: https://s3.us-east-1.amazonaws.com/csld8xmsdksdf8s9sk3mmdjsdifkjksdijsldk/Transcribe2.wav. The wav file is valid. I can download it in my browser and replay it (and it sounds like the origin recording), so I think we can rule out an invalid input file, file permissions, etc.
I am using java version: 1.8.0_275 for mac.
I expect my program to give me back the transcribed text: "Hello amazon Subscribe, what is this?"
Here is the actual program output, including exception:
/Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home/bin/java "-javaagent:/Applications/IntelliJ IDEA CE.app/Contents/lib/idea_rt.jar=60898:/Applications/IntelliJ IDEA CE.app/Contents/bin" -Dfile.encoding=UTF-8 -classpath /Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home/jre/lib/charsets.jar:/Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home/jre/lib/ext/cldrdata.jar:/Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home/jre/lib/ext/dnsns.jar:/Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home/jre/lib/ext/jaccess.jar:/Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home/jre/lib/ext/localedata.jar:/Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home/jre/lib/ext/nashorn.jar:/Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home/jre/lib/ext/sunec.jar:/Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home/jre/lib/ext/sunjce_provider.jar:/Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home/jre/lib/ext/sunpkcs11.jar:/Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home/jre/lib/ext/zipfs.jar:/Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home/jre/lib/jce.jar:/Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home/jre/lib/jfr.jar:/Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home/jre/lib/jsse.jar:/Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home/jre/lib/management-agent.jar:/Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home/jre/lib/resources.jar:/Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home/jre/lib/rt.jar:/Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home/lib/dt.jar:/Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home/lib/jconsole.jar:/Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home/lib/sa-jdi.jar:/Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home/lib/tools.jar:/Users/cdornin/work/transcribe/target/classes:/Users/cdornin/.m2/repository/org/apiguardian/apiguardian-api/1.0.0/apiguardian-api-1.0.0.jar:/Users/cdornin/.m2/repository/org/junit/platform/junit-platform-commons/1.4.0/junit-platform-commons-1.4.0.jar:/Users/cdornin/.m2/repository/org/slf4j/slf4j-log4j12/1.7.25/slf4j-log4j12-1.7.25.jar:/Users/cdornin/.m2/repository/org/slf4j/slf4j-api/1.7.25/slf4j-api-1.7.25.jar:/Users/cdornin/.m2/repository/log4j/log4j/1.2.17/log4j-1.2.17.jar:/Users/cdornin/.m2/repository/software/amazon/awssdk/transcribe/2.15.65/transcribe-2.15.65.jar:/Users/cdornin/.m2/repository/software/amazon/awssdk/protocol-core/2.15.65/protocol-core-2.15.65.jar:/Users/cdornin/.m2/repository/software/amazon/awssdk/aws-json-protocol/2.15.65/aws-json-protocol-2.15.65.jar:/Users/cdornin/.m2/repository/software/amazon/awssdk/sdk-core/2.15.65/sdk-core-2.15.65.jar:/Users/cdornin/.m2/repository/software/amazon/awssdk/profiles/2.15.65/profiles-2.15.65.jar:/Users/cdornin/.m2/repository/org/reactivestreams/reactive-streams/1.0.2/reactive-streams-1.0.2.jar:/Users/cdornin/.m2/repository/software/amazon/awssdk/auth/2.15.65/auth-2.15.65.jar:/Users/cdornin/.m2/repository/software/amazon/eventstream/eventstream/1.0.1/eventstream-1.0.1.jar:/Users/cdornin/.m2/repository/software/amazon/awssdk/http-client-spi/2.15.65/http-client-spi-2.15.65.jar:/Users/cdornin/.m2/repository/software/amazon/awssdk/regions/2.15.65/regions-2.15.65.jar:/Users/cdornin/.m2/repository/software/amazon/awssdk/annotations/2.15.65/annotations-2.15.65.jar:/Users/cdornin/.m2/repository/software/amazon/awssdk/utils/2.15.65/utils-2.15.65.jar:/Users/cdornin/.m2/repository/software/amazon/awssdk/aws-core/2.15.65/aws-core-2.15.65.jar:/Users/cdornin/.m2/repository/software/amazon/awssdk/metrics-spi/2.15.65/metrics-spi-2.15.65.jar:/Users/cdornin/.m2/repository/software/amazon/awssdk/apache-client/2.15.65/apache-client-2.15.65.jar:/Users/cdornin/.m2/repository/org/apache/httpcomponents/httpclient/4.5.13/httpclient-4.5.13.jar:/Users/cdornin/.m2/repository/commons-codec/commons-codec/1.11/commons-codec-1.11.jar:/Users/cdornin/.m2/repository/org/apache/httpcomponents/httpcore/4.4.11/httpcore-4.4.11.jar:/Users/cdornin/.m2/repository/software/amazon/awssdk/netty-nio-client/2.15.65/netty-nio-client-2.15.65.jar:/Users/cdornin/.m2/repository/io/netty/netty-codec-http/4.1.53.Final/netty-codec-http-4.1.53.Final.jar:/Users/cdornin/.m2/repository/io/netty/netty-codec-http2/4.1.53.Final/netty-codec-http2-4.1.53.Final.jar:/Users/cdornin/.m2/repository/io/netty/netty-codec/4.1.53.Final/netty-codec-4.1.53.Final.jar:/Users/cdornin/.m2/repository/io/netty/netty-transport/4.1.53.Final/netty-transport-4.1.53.Final.jar:/Users/cdornin/.m2/repository/io/netty/netty-resolver/4.1.53.Final/netty-resolver-4.1.53.Final.jar:/Users/cdornin/.m2/repository/io/netty/netty-common/4.1.53.Final/netty-common-4.1.53.Final.jar:/Users/cdornin/.m2/repository/io/netty/netty-buffer/4.1.53.Final/netty-buffer-4.1.53.Final.jar:/Users/cdornin/.m2/repository/io/netty/netty-handler/4.1.53.Final/netty-handler-4.1.53.Final.jar:/Users/cdornin/.m2/repository/io/netty/netty-transport-native-epoll/4.1.53.Final/netty-transport-native-epoll-4.1.53.Final-linux-x86_64.jar:/Users/cdornin/.m2/repository/io/netty/netty-transport-native-unix-common/4.1.53.Final/netty-transport-native-unix-common-4.1.53.Final.jar:/Users/cdornin/.m2/repository/com/typesafe/netty/netty-reactive-streams-http/2.0.4/netty-reactive-streams-http-2.0.4.jar:/Users/cdornin/.m2/repository/com/typesafe/netty/netty-reactive-streams/2.0.4/netty-reactive-streams-2.0.4.jar:/Users/cdornin/.m2/repository/software/amazon/awssdk/transcribestreaming/2.15.65/transcribestreaming-2.15.65.jar:/Users/cdornin/.m2/repository/com/amazonaws/aws-java-sdk-s3/1.11.939/aws-java-sdk-s3-1.11.939.jar:/Users/cdornin/.m2/repository/com/amazonaws/aws-java-sdk-kms/1.11.939/aws-java-sdk-kms-1.11.939.jar:/Users/cdornin/.m2/repository/com/amazonaws/aws-java-sdk-core/1.11.939/aws-java-sdk-core-1.11.939.jar:/Users/cdornin/.m2/repository/commons-logging/commons-logging/1.1.3/commons-logging-1.1.3.jar:/Users/cdornin/.m2/repository/software/amazon/ion/ion-java/1.0.2/ion-java-1.0.2.jar:/Users/cdornin/.m2/repository/com/fasterxml/jackson/dataformat/jackson-dataformat-cbor/2.6.7/jackson-dataformat-cbor-2.6.7.jar:/Users/cdornin/.m2/repository/joda-time/joda-time/2.8.1/joda-time-2.8.1.jar:/Users/cdornin/.m2/repository/com/amazonaws/jmespath-java/1.11.939/jmespath-java-1.11.939.jar:/Users/cdornin/.m2/repository/com/amazonaws/aws-java-sdk-transcribe/1.11.939/aws-java-sdk-transcribe-1.11.939.jar:/Users/cdornin/.m2/repository/io/minio/minio/8.0.3/minio-8.0.3.jar:/Users/cdornin/.m2/repository/com/carrotsearch/thirdparty/simple-xml-safe/2.7.1/simple-xml-safe-2.7.1.jar:/Users/cdornin/.m2/repository/com/google/guava/guava/29.0-jre/guava-29.0-jre.jar:/Users/cdornin/.m2/repository/com/google/guava/failureaccess/1.0.1/failureaccess-1.0.1.jar:/Users/cdornin/.m2/repository/com/google/guava/listenablefuture/9999.0-empty-to-avoid-conflict-with-guava/listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar:/Users/cdornin/.m2/repository/com/google/code/findbugs/jsr305/3.0.2/jsr305-3.0.2.jar:/Users/cdornin/.m2/repository/org/checkerframework/checker-qual/2.11.1/checker-qual-2.11.1.jar:/Users/cdornin/.m2/repository/com/google/errorprone/error_prone_annotations/2.3.4/error_prone_annotations-2.3.4.jar:/Users/cdornin/.m2/repository/com/google/j2objc/j2objc-annotations/1.3/j2objc-annotations-1.3.jar:/Users/cdornin/.m2/repository/com/squareup/okhttp3/okhttp/4.8.1/okhttp-4.8.1.jar:/Users/cdornin/.m2/repository/com/squareup/okio/okio/2.7.0/okio-2.7.0.jar:/Users/cdornin/.m2/repository/org/jetbrains/kotlin/kotlin-stdlib-common/1.3.70/kotlin-stdlib-common-1.3.70.jar:/Users/cdornin/.m2/repository/org/jetbrains/kotlin/kotlin-stdlib/1.3.72/kotlin-stdlib-1.3.72.jar:/Users/cdornin/.m2/repository/org/jetbrains/annotations/13.0/annotations-13.0.jar:/Users/cdornin/.m2/repository/com/fasterxml/jackson/core/jackson-annotations/2.11.2/jackson-annotations-2.11.2.jar:/Users/cdornin/.m2/repository/com/fasterxml/jackson/core/jackson-core/2.11.2/jackson-core-2.11.2.jar:/Users/cdornin/.m2/repository/com/fasterxml/jackson/core/jackson-databind/2.11.2/jackson-databind-2.11.2.jar com.amazonaws.transcribe.AmazonTranscribeServiceImpl
log4j:WARN Continuable parsing error 2 and column 30
log4j:WARN Document root element "Configuration", must match DOCTYPE root "null".
log4j:WARN Continuable parsing error 2 and column 30
log4j:WARN Document is invalid: no grammar found.
log4j:ERROR DOM element is - not a <log4j:configuration> element.
log4j:WARN No appenders could be found for logger (com.amazonaws.AmazonWebServiceClient).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
Exception in thread "main" com.amazonaws.services.transcribe.model.AmazonTranscribeException: null (Service: AmazonTranscribe; Status Code: 400; Error Code: null; Request ID: 6BBE51FDC2CA981B; Proxy: null)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.handleErrorResponse(AmazonHttpClient.java:1819)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.handleServiceErrorResponse(AmazonHttpClient.java:1403)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeOneRequest(AmazonHttpClient.java:1372)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeHelper(AmazonHttpClient.java:1145)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.doExecute(AmazonHttpClient.java:802)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeWithTimer(AmazonHttpClient.java:770)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.execute(AmazonHttpClient.java:744)
at com.amazonaws.http.AmazonHttpClient$RequestExecutor.access$500(AmazonHttpClient.java:704)
at com.amazonaws.http.AmazonHttpClient$RequestExecutionBuilderImpl.execute(AmazonHttpClient.java:686)
at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:550)
at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:530)
at com.amazonaws.services.transcribe.AmazonTranscribeClient.doInvoke(AmazonTranscribeClient.java:1995)
at com.amazonaws.services.transcribe.AmazonTranscribeClient.invoke(AmazonTranscribeClient.java:1962)
at com.amazonaws.services.transcribe.AmazonTranscribeClient.invoke(AmazonTranscribeClient.java:1951)
at com.amazonaws.services.transcribe.AmazonTranscribeClient.executeStartTranscriptionJob(AmazonTranscribeClient.java:1712)
at com.amazonaws.services.transcribe.AmazonTranscribeClient.startTranscriptionJob(AmazonTranscribeClient.java:1681)
at com.amazonaws.transcribe.AmazonTranscribeServiceImpl.callTranscribeService(AmazonTranscribeServiceImpl.java:34)
at com.amazonaws.transcribe.AmazonTranscribeServiceImpl.main(AmazonTranscribeServiceImpl.java:20)
Here is my java code (add your aws key and secret)
package com.amazonaws.transcribe;
import com.amazonaws.ClientConfiguration;
import com.amazonaws.auth.DefaultAWSCredentialsProviderChain;
import com.amazonaws.client.builder.AwsClientBuilder;
import com.amazonaws.services.transcribe.AmazonTranscribe;
import com.amazonaws.services.transcribe.AmazonTranscribeClientBuilder;
import com.amazonaws.services.transcribe.model.Media;
import com.amazonaws.services.transcribe.model.StartTranscriptionJobRequest;
import com.amazonaws.services.transcribe.model.StartTranscriptionJobResult;
/**
* #author ravindu.s
*/
public class AmazonTranscribeServiceImpl {
public static void main(String[] args) throws Exception {
System.setProperty("aws.accessKeyId", "myKey");
System.setProperty("aws.secretAccessKey", "mySecret");
callTranscribeService("https://s3.us-east-1.amazonaws.com/csld8xmsdksdf8s9sk3mmdjsdifkjksdijsldk/Transcribe2.wav");
}
public static void callTranscribeService(String mediaFile) {
ClientConfiguration clientConfig = new ClientConfiguration();
clientConfig.setConnectionTimeout(60000);
clientConfig.setMaxConnections(100);
clientConfig.setSocketTimeout(60000);
AmazonTranscribe transcribeClient = AmazonTranscribeClientBuilder.standard().withCredentials(
DefaultAWSCredentialsProviderChain.getInstance()).withEndpointConfiguration(
new AwsClientBuilder.EndpointConfiguration(mediaFile, "us-east-1")).withClientConfiguration(clientConfig).build();
StartTranscriptionJobRequest request = buildRequest(mediaFile);
StartTranscriptionJobResult response = transcribeClient.startTranscriptionJob(request);
System.out.println(response.getTranscriptionJob().getTranscriptionJobStatus());
}
private static StartTranscriptionJobRequest buildRequest(String mediaFile) {
StartTranscriptionJobRequest request = new StartTranscriptionJobRequest();
request.setMediaSampleRateHertz(16000);
request.setMediaFormat("wav");
request.setLanguageCode("en-US");
request.setTranscriptionJobName("JOB-001");
Media media = new Media();
media.setMediaFileUri(mediaFile);
request.setMedia(media);
return request;
}
}
Here is my pom.xml file
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>play</groupId>
<artifactId>transcribeTest</artifactId>
<version>1.0-SNAPSHOT</version>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>8</source>
<target>8</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<!--<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.4.2</version>
<scope>test</scope>
</dependency>-->
<!-- https://mvnrepository.com/artifact/junit/junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.4.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-commons</artifactId>
<version>1.4.0</version>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-launcher</artifactId>
<version>1.4.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.25</version>
</dependency>
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>transcribe</artifactId>
<version>2.15.65</version>
</dependency>
<!-- https://mvnrepository.com/artifact/software.amazon.awssdk/transcribestreaming -->
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>transcribestreaming</artifactId>
<version>2.15.65</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.amazonaws/aws-java-sdk-s3 -->
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-s3</artifactId>
<version>1.11.939</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.amazonaws/aws-java-sdk-transcribe -->
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-transcribe</artifactId>
<version>1.11.939</version>
</dependency>
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>8.0.3</version>
</dependency>
</dependencies>
</project>
Here is a Java Code Example that transcribes an audio file located in C:. This is V2.
import org.reactivestreams.Publisher;
import org.reactivestreams.Subscriber;
import org.reactivestreams.Subscription;
import software.amazon.awssdk.core.SdkBytes;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.transcribestreaming.TranscribeStreamingAsyncClient;
import software.amazon.awssdk.services.transcribestreaming.model.*;
import javax.sound.sampled.*;
import java.io.*;
import java.net.URISyntaxException;
import java.nio.ByteBuffer;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicLong;
public class TranscribeStreamingDemoFile {
private static final Region REGION = Region.US_EAST_1;
private static TranscribeStreamingAsyncClient client;
public static void main(String args[]) throws URISyntaxException, ExecutionException, InterruptedException, LineUnavailableException {
client = TranscribeStreamingAsyncClient.builder()
.region(REGION)
.build();
CompletableFuture<Void> result = client.startStreamTranscription(getRequest(16000),
new AudioStreamPublisher(getStreamFromFile()),
getResponseHandler());
result.get();
client.close();
}
private static InputStream getStreamFromFile() {
try {
File inputFile = new File("C:\\test.wav");
InputStream audioStream = new FileInputStream(inputFile);
return audioStream;
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
}
}
private static StartStreamTranscriptionRequest getRequest(Integer mediaSampleRateHertz) {
return StartStreamTranscriptionRequest.builder()
.languageCode(LanguageCode.EN_US)
.mediaEncoding(MediaEncoding.PCM)
.mediaSampleRateHertz(mediaSampleRateHertz)
.build();
}
private static StartStreamTranscriptionResponseHandler getResponseHandler() {
return StartStreamTranscriptionResponseHandler.builder()
.onResponse(r -> {
System.out.println("Received Initial response");
})
.onError(e -> {
System.out.println(e.getMessage());
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
System.out.println("Error Occurred: " + sw.toString());
})
.onComplete(() -> {
System.out.println("=== All records stream successfully ===");
})
.subscriber(event -> {
List<Result> results = ((TranscriptEvent) event).transcript().results();
if (results.size() > 0) {
if (!results.get(0).alternatives().get(0).transcript().isEmpty()) {
System.out.println(results.get(0).alternatives().get(0).transcript());
}
}
})
.build();
}
private static class AudioStreamPublisher implements Publisher<AudioStream> {
private final InputStream inputStream;
private static Subscription currentSubscription;
private AudioStreamPublisher(InputStream inputStream) {
this.inputStream = inputStream;
}
#Override
public void subscribe(Subscriber<? super AudioStream> s) {
if (this.currentSubscription == null) {
this.currentSubscription = new SubscriptionImpl(s, inputStream);
} else {
this.currentSubscription.cancel();
this.currentSubscription = new SubscriptionImpl(s, inputStream);
}
s.onSubscribe(currentSubscription);
}
}
public static class SubscriptionImpl implements Subscription {
private static final int CHUNK_SIZE_IN_BYTES = 1024 * 1;
private final Subscriber<? super AudioStream> subscriber;
private final InputStream inputStream;
private ExecutorService executor = Executors.newFixedThreadPool(1);
private AtomicLong demand = new AtomicLong(0);
SubscriptionImpl(Subscriber<? super AudioStream> s, InputStream inputStream) {
this.subscriber = s;
this.inputStream = inputStream;
}
#Override
public void request(long n) {
if (n <= 0) {
subscriber.onError(new IllegalArgumentException("Demand must be positive"));
}
demand.getAndAdd(n);
executor.submit(() -> {
try {
do {
ByteBuffer audioBuffer = getNextEvent();
if (audioBuffer.remaining() > 0) {
AudioEvent audioEvent = audioEventFromBuffer(audioBuffer);
subscriber.onNext(audioEvent);
} else {
subscriber.onComplete();
break;
}
} while (demand.decrementAndGet() > 0);
} catch (Exception e) {
subscriber.onError(e);
}
});
}
#Override
public void cancel() {
executor.shutdown();
}
private ByteBuffer getNextEvent() {
ByteBuffer audioBuffer = null;
byte[] audioBytes = new byte[CHUNK_SIZE_IN_BYTES];
int len = 0;
try {
len = inputStream.read(audioBytes);
if (len <= 0) {
audioBuffer = ByteBuffer.allocate(0);
} else {
audioBuffer = ByteBuffer.wrap(audioBytes, 0, len);
}
} catch (IOException e) {
throw new UncheckedIOException(e);
}
return audioBuffer;
}
private AudioEvent audioEventFromBuffer(ByteBuffer bb) {
return AudioEvent.builder()
.audioChunk(SdkBytes.fromByteBuffer(bb))
.build();
}
}
}
I had a small mistake in my code. This line wasn't necessary and when I removed, it worked:
withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration(mediaFile, "us-east-1"))

GZIP not working with Protocol Buffer. Snappy does

I am learning Protocol Buffer in Java. After basic serialization/deserialization, I am attempting to put compression.
In the provided code, I tried to use GZIP but while deserializing, it reads one extra record. It can be seen in System.out printing an extra "," at end.
This problem does not happen when using same code, but with Snappy (Commented in code below). Any suggestions if I am doing something wrong? Or if I can bypass the problem.
Output with GZIP:
id0,NAME0
,
Output with Snappy:
id0,NAME0
Code:
package testPkg;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
import org.xerial.snappy.SnappyInputStream;
import org.xerial.snappy.SnappyOutputStream;
public class TestProtoBuf {
public static String fileNm = "C:/testFile";
public static void main(String[] args) throws IOException {
// creating data
List<DataClass> list = new ArrayList<>();
for (int i = 0; i < 1; i++) {
list.add(new DataClass("id" + i, "NAME" + i));
}
// writing data
try (OutputStream os = new GZIPOutputStream(new BufferedOutputStream(new FileOutputStream(fileNm)))
/*OutputStream os = new SnappyOutputStream(new BufferedOutputStream(new FileOutputStream(fileNm)))*/) {
for (DataClass dc : list) {
DataClassProtoBufProxy.DataClass.Builder bld = DataClassProtoBufProxy.DataClass.newBuilder();
bld.setId(dc.id);
bld.setName(dc.name);
bld.build().writeDelimitedTo(os);
}
os.flush();
}
// reading data
try (InputStream is = new GZIPInputStream(new BufferedInputStream(new FileInputStream(fileNm)))
/*InputStream is = new SnappyInputStream(new BufferedInputStream(new FileInputStream(fileNm)))*/) {
while (is.available() > 0) {
DataClassProtoBufProxy.DataClass.Builder bld = DataClassProtoBufProxy.DataClass.newBuilder();
bld.mergeDelimitedFrom(is);
DataClassProtoBufProxy.DataClass dc = bld.build();
System.out.println(dc.getId() + "," + dc.getName());
}
}
}
static class DataClass {
private String id;
private String name;
DataClass() {
id = null;
name = null;
}
DataClass(String id, String name) {
this.id = id;
this.name = name;
}
}
}
The proto file:
// [START declaration]
syntax = "proto3";
package testPkg;
// [END declaration]
// [START java_declaration]
option java_package = "testPkg";
option java_outer_classname = "DataClassProtoBufProxy";
// [END java_declaration]
// [START messages]
message DataClass {
string id = 1;
string name = 20;
}
// [END messages]
Maven dependencies:
<!-- https://mvnrepository.com/artifact/com.google.protobuf/protobuf-java -->
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>3.2.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.xerial.snappy/snappy-java -->
<dependency>
<groupId>org.xerial.snappy</groupId>
<artifactId>snappy-java</artifactId>
<version>1.1.2.6</version>
</dependency>

Java tesseract return co-ordinates of text location

I am using Java in eclipse and want to return the co-ordinates of all recognized text which is found. My code which I attained through tess4j currently outputs all of the text found, this code is below:
import java.awt.color.ColorSpace;
import java.awt.image.BufferedImage;
import java.awt.image.ColorConvertOp;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import net.sourceforge.tess4j.*;
public class TesseractExample {
public static void main(String[] args) throws IOException
{
try
{
String x = System.getProperty("user.dir");
File b = new File(x+"/inDCM");
File imageFile = new File(b+"/surrey.png");
BufferedImage img = ImageIO.read(imageFile);
Tesseract instance = Tesseract.getInstance();
ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_GRAY);
ColorConvertOp op = new ColorConvertOp(cs, null);
op.filter(img, img);
try
{
String result = instance.doOCR(img);
System.out.println("The result is: " + result);
}
catch (TesseractException e)
{
System.out.println("error:" + e);
}
}finally{
}
}}
Is it possible to retrieve the co-ordinates?
Tess4j will be really helpful here for you. This is an example I found on the test cases
/**
* Test of getSegmentedRegions method, of class Tesseract.
*
* #throws java.lang.Exception
*/
#Test
public void testGetSegmentedRegions() throws Exception {
logger.info("getSegmentedRegions at given TessPageIteratorLevel");
File imageFile = new File(testResourcesDataPath, "eurotext.png");
BufferedImage bi = ImageIO.read(imageFile);
int level = TessPageIteratorLevel.RIL_SYMBOL;
logger.info("PageIteratorLevel: " + Utils.getConstantName(level, TessPageIteratorLevel.class));
List<Rectangle> result = instance.getSegmentedRegions(bi, level);
for (int i = 0; i < result.size(); i++) {
Rectangle rect = result.get(i);
logger.info(String.format("Box[%d]: x=%d, y=%d, w=%d, h=%d", i, rect.x, rect.y, rect.width, rect.height));
}
assertTrue(result.size() > 0);
}
The TessPageIteratorLevel will define how to segmentate the content of the image.(i.e.: character or word)
TessPageIteratorLevel Options
/**
* Block of text/image/separator line.
*/
public static final int RIL_BLOCK = 0;
/**
* Paragraph within a block.
*/
public static final int RIL_PARA = 1;
/**
* Line within a paragraph.
*/
public static final int RIL_TEXTLINE = 2;
/**
* Word within a textline.
*/
public static final int RIL_WORD = 3;
/**
* Symbol/character within a word.
*/
public static final int RIL_SYMBOL = 4;
You can get the coordinates through ResultIterator object available in the low-level TessBaseAPI API. Code examples can be found in unit tests in the project's repo.

Download Manager In java using multi threading

as you have seen before I'm working on a download manager in java, I have asked This Question and I have read This Question But These hadn't solve my problem. now I have wrote another code in java. but there is a problem. when download finishes file is larger than it's size and related software can't read it
This is image of my code execution :
as you see file size is about 9.43 MB
This is My project directory's image:
as you see my downloaded filesize is about 13 MB
So what is my Prooblem?
here is my complete source code
Main Class:
package download.manager;
import java.util.Scanner;
/**
*
* #author Behzad
*/
public class DownloadManager {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("Enter url here : ");
String url = input.nextLine();
DownloadInfo information = new DownloadInfo(url);
}
}
DownloadInfo Class:
package download.manager;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
public class DownloadInfo {
private String downloadUrl;
private String fileName;
private String fileExtension;
private URL nonStringUrl;
private HttpURLConnection connection;
private int fileSize;
private int remainingByte;
private RandomAccessFile outputFile;
public DownloadInfo(String downloadUrl) {
this.downloadUrl = downloadUrl;
initiateInformation();
}
private void initiateInformation(){
fileName = downloadUrl.substring(downloadUrl.lastIndexOf('/') + 1, downloadUrl.length());
fileExtension = fileName.substring(fileName.lastIndexOf('.') + 1, fileName.length());
try {
nonStringUrl = new URL(downloadUrl);
connection = (HttpURLConnection) nonStringUrl.openConnection();
fileSize = ((connection.getContentLength()));
System.out.printf("File Size is : %d \n", fileSize);
System.out.printf("Remain File Size is : %d \n", fileSize % 8);
remainingByte = fileSize % 8;
fileSize /= 8;
outputFile = new RandomAccessFile(fileName, "rw");
} catch (MalformedURLException ex) {
Logger.getLogger(DownloadInfo.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(DownloadInfo.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.printf("File Name is : %s\n", fileName);
System.out.printf("File Extension is : %s\n", fileExtension);
System.out.printf("Partition Size is : %d MB\n", fileSize);
int first = 0 , last = fileSize - 1;
ExecutorService thread_pool = Executors.newFixedThreadPool(8);
for(int i=0;i<8;i++){
if(i != 7){
thread_pool.submit(new Downloader(nonStringUrl, first, last, (i+1), outputFile));
}
else{
thread_pool.submit(new Downloader(nonStringUrl, first, last + remainingByte, (i+1), outputFile));
}
first = last + 1;
last += fileSize;
}
thread_pool.shutdown();
try {
thread_pool.awaitTermination(Long.MAX_VALUE, TimeUnit.MILLISECONDS);
} catch (InterruptedException ex) {
Logger.getLogger(DownloadInfo.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
and this is my downloader class:
package download.manager;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
* #author Behzad
*/
public class Downloader implements Runnable{
private URL downloadURL;
private int startByte;
private int endByte;
private int threadNum;
private RandomAccessFile outputFile;
private InputStream stream;
public Downloader(URL downloadURL,int startByte, int endByte, int threadNum, RandomAccessFile outputFile) {
this.downloadURL = downloadURL;
this.startByte = startByte;
this.endByte = endByte;
this.threadNum = threadNum;
this.outputFile = outputFile;
}
#Override
public void run() {
download();
}
private void download(){
try {
System.out.printf("Thread %d is working...\n" , threadNum);
HttpURLConnection httpURLConnection = (HttpURLConnection) downloadURL.openConnection();
httpURLConnection.setRequestProperty("Range", "bytes="+startByte+"-"+endByte);
httpURLConnection.connect();
outputFile.seek(startByte);
stream = httpURLConnection.getInputStream();
while(true){
int nextByte = stream.read();
if(nextByte == -1){
break;
}
outputFile.write(endByte);
}
} catch (IOException ex) {
Logger.getLogger(Downloader.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
This file is MP4 for as you seen, but Gom can't play it
Would you please help me?
OoOoOopppps finally I found what is the problem , It's all on seek method. because i have a file and 8 threads. so seek method changes the cursor repeatedly and make larger file and unexecutable file :), But I'm so sorry . I can't show whole code :)

Reading QRCode with Zxing in Java

Some questions about using Zxing...
I write the following code to read barcode from an image:
public class BarCodeDecode
{
/**
* #param args
*/
public static void main(String[] args)
{
try
{
String tmpImgFile = "D:\\FormCode128.TIF";
Map<DecodeHintType,Object> tmpHintsMap = new EnumMap<DecodeHintType, Object>(DecodeHintType.class);
tmpHintsMap.put(DecodeHintType.TRY_HARDER, Boolean.TRUE);
tmpHintsMap.put(DecodeHintType.POSSIBLE_FORMATS, EnumSet.allOf(BarcodeFormat.class));
tmpHintsMap.put(DecodeHintType.PURE_BARCODE, Boolean.FALSE);
File tmpFile = new File(tmpImgFile);
String tmpRetString = BarCodeUtil.decode(tmpFile, tmpHintsMap);
//String tmpRetString = BarCodeUtil.decode(tmpFile, null);
System.out.println(tmpRetString);
}
catch (Exception tmpExpt)
{
System.out.println("main: " + "Excpt err! (" + tmpExpt.getMessage() + ")");
}
System.out.println("main: " + "Program end.");
}
}
public class BarCodeUtil
{
private static BarcodeFormat DEFAULT_BARCODE_FORMAT = BarcodeFormat.CODE_128;
/**
* Decode method used to read image or barcode itself, and recognize the barcode,
* get the encoded contents and returns it.
* #param whatFile image that need to be read.
* #param config configuration used when reading the barcode.
* #return decoded results from barcode.
*/
public static String decode(File whatFile, Map<DecodeHintType, Object> whatHints) throws Exception
{
// check the required parameters
if (whatFile == null || whatFile.getName().trim().isEmpty())
throw new IllegalArgumentException("File not found, or invalid file name.");
BufferedImage tmpBfrImage;
try
{
tmpBfrImage = ImageIO.read(whatFile);
}
catch (IOException tmpIoe)
{
throw new Exception(tmpIoe.getMessage());
}
if (tmpBfrImage == null)
throw new IllegalArgumentException("Could not decode image.");
LuminanceSource tmpSource = new BufferedImageLuminanceSource(tmpBfrImage);
BinaryBitmap tmpBitmap = new BinaryBitmap(new HybridBinarizer(tmpSource));
MultiFormatReader tmpBarcodeReader = new MultiFormatReader();
Result tmpResult;
String tmpFinalResult;
try
{
if (whatHints != null && ! whatHints.isEmpty())
tmpResult = tmpBarcodeReader.decode(tmpBitmap, whatHints);
else
tmpResult = tmpBarcodeReader.decode(tmpBitmap);
// setting results.
tmpFinalResult = String.valueOf(tmpResult.getText());
}
catch (Exception tmpExcpt)
{
throw new Exception("BarCodeUtil.decode Excpt err - " + tmpExcpt.toString() + " - " + tmpExcpt.getMessage());
}
return tmpFinalResult;
}
}
I try to read the following two images that contains code128 and QRCode.
It can work for the code128 but not for the QRCode.
Any one knows why...
Please go through this link for complete Tutorial. The author of this code is Joe. I have not developed this code, so I am just doing Copy paste to make sure this is available in case link is broken.
The author is using ZXing(Zebra Crossing Library) you can download it from here, for this tutorial.
QR Code Write and Read Program in Java:
package com.javapapers.java;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.imageio.ImageIO;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.NotFoundException;
import com.google.zxing.Result;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
public class QRCode {
public static void main(String[] args) throws WriterException, IOException,
NotFoundException {
String qrCodeData = "Hello World!";
String filePath = "QRCode.png";
String charset = "UTF-8"; // or "ISO-8859-1"
Map<EncodeHintType, ErrorCorrectionLevel> hintMap = new HashMap<EncodeHintType, ErrorCorrectionLevel>();
hintMap.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);
createQRCode(qrCodeData, filePath, charset, hintMap, 200, 200);
System.out.println("QR Code image created successfully!");
System.out.println("Data read from QR Code: "
+ readQRCode(filePath, charset, hintMap));
}
public static void createQRCode(String qrCodeData, String filePath,
String charset, Map hintMap, int qrCodeheight, int qrCodewidth)
throws WriterException, IOException {
BitMatrix matrix = new MultiFormatWriter().encode(
new String(qrCodeData.getBytes(charset), charset),
BarcodeFormat.QR_CODE, qrCodewidth, qrCodeheight, hintMap);
MatrixToImageWriter.writeToFile(matrix, filePath.substring(filePath
.lastIndexOf('.') + 1), new File(filePath));
}
public static String readQRCode(String filePath, String charset, Map hintMap)
throws FileNotFoundException, IOException, NotFoundException {
BinaryBitmap binaryBitmap = new BinaryBitmap(new HybridBinarizer(
new BufferedImageLuminanceSource(
ImageIO.read(new FileInputStream(filePath)))));
Result qrCodeResult = new MultiFormatReader().decode(binaryBitmap,
hintMap);
return qrCodeResult.getText();
}
}
Maven dependency for the ZXing QR Code library:
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>2.2</version>
</dependency>
Curiously your code works for me, but I had to remove the follow hint.
tmpHintsMap.put(DecodeHintType.PURE_BARCODE, Boolean.FALSE);
When my image is not pure barcode, this hint broke my result.
Thank you!
This Code worked for me.
public static List<string> ScanForBarcodes(string path)
{
return ScanForBarcodes(new Bitmap(path));
}
public static List<string> ScanForBarcodes(Bitmap bitmap)
{
// initialize a new Barcode reader.
BarcodeReader reader = new BarcodeReader
{
TryHarder = true, // TryHarder is slower but recognizes more Barcodes
PossibleFormats = new List<BarcodeFormat> // in the ZXing There is an Enum where all supported barcodeFormats were contained
{
BarcodeFormat.CODE_128,
BarcodeFormat.QR_CODE,
//BarcodeFormat. ... ;
}
};
return reader.DecodeMultiple(bitmap).Select(result => result.Text).ToList(); // return only the barcode string.
// If you want the full Result use: return reader.DecodeMultiple(bitmap);
}
Did you use this (ZXing.Net) Lib?

Categories

Resources