Can't import ZKStringSerializer$ - java

I want to create kafka topic in Java. I have a sample code from stackoverflow. But the problem is that I couldn't import ZKStringSerializer$ and ZkUtils. I have all maven dependencies. What is the reason? Her is the code:
import kafka.admin.AdminUtils;
import kafka.utils.ZKStringSerializer$;
import kafka.utils.ZkUtils;
import org.I0Itec.zkclient.ZkClient;
import org.I0Itec.zkclient.ZkConnection;
public class CreateKafkaTopic {
public static void main(String[] args) {
ZkClient zkClient = null;
ZkUtils zkUtils = null;
try {
String zookeeperHosts = "192.168.20.1:2181"; // If multiple zookeeper then -> String zookeeperHosts = "192.168.20.1:2181,192.168.20.2:2181";
int sessionTimeOutInMs = 15 * 1000; // 15 secs
int connectionTimeOutInMs = 10 * 1000; // 10 secs
zkClient = new ZkClient(zookeeperHosts, sessionTimeOutInMs, connectionTimeOutInMs, ZKStringSerializer$.MODULE$);
zkUtils = new ZkUtils(zkClient, new ZkConnection(zookeeperHosts), false);
String topicName = "testTopic";
int noOfPartitions = 2;
int noOfReplication = 3;
Properties topicConfiguration = new Properties();
AdminUtils.createTopic(zkUtils, topicName, noOfPartitions, noOfReplication, topicConfiguration);
} catch (Exception ex) {
ex.printStackTrace();
} finally {
if (zkClient != null) {
zkClient.close();
}
}
}
}
Here is maven dependency:
<!-- https://mvnrepository.com/artifact/org.apache.kafka/kafka -->
<dependency>
<groupId>org.apache.kafka</groupId>
<artifactId>kafka_2.13</artifactId>
<version>2.6.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.101tec/zkclient -->
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<version>0.11</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.kafka/kafka-streams-test-utils -->
<dependency>
<groupId>org.apache.kafka</groupId>
<artifactId>kafka-streams-test-utils</artifactId>
<version>2.7.0</version>
</dependency>

I assume you copied from this post? If so, read the very top of that accepted answer.
Zookeeper is a deprecated method to create topics.
Use AdminClient.createTopics or a higher-level framework like dropwizard-kafka configuration or spring-kafka's #Bean to create topics
Also, use kafka-clients dependency, not the kafka_[scala.version] depdendency

Related

How to replace specific line only on 1st occurence by mentioning keyword

I have below pom.xml file. I want to replace the version of the project which is in line 7.
I will be able to provide<version> tag alone but not complete version details.
Expecting a code which finds the 1st <version> tag line and replace that with <version>1.0.1</version>
I started with the below java code but which is currently replacing the whole version tag in the entire pom.xml.
How do I replace 1st <version> tag line alone with <version>1.0.1</version>
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>com.myspace</groupId>
<artifactId>Test</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>kjar</packaging>
<name>Test</name>
<description></description>
<dependencies>
<dependency>
<groupId>org.kie</groupId>
<artifactId>kie-api</artifactId>
<version>7.46.0.Final</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.kie</groupId>
<artifactId>kie-internal</artifactId>
<version>7.46.0.Final</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.optaplanner</groupId>
<artifactId>optaplanner-core</artifactId>
<version>7.46.0.Final</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.optaplanner</groupId>
<artifactId>optaplanner-persistence-jaxb</artifactId>
<version>7.46.0.Final</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.thoughtworks.xstream</groupId>
<artifactId>xstream</artifactId>
<version>1.4.11.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.kie</groupId>
<artifactId>kie-maven-plugin</artifactId>
<version>7.46.0.Final</version>
<extensions>true</extensions>
</plugin>
</plugins>
</build>
</project>
Java code
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Scanner;
public class OverwriteLine {
public static void main(String args[]) throws IOException {
//Instantiating the File class
String cloneDirectoryPath = "D:\\project\\localrepo117";
String filePath = cloneDirectoryPath+"\\pom.xml";
//Instantiating the Scanner class to read the file
Scanner sc = new Scanner(new File(filePath));
//instantiating the StringBuffer class
StringBuffer buffer = new StringBuffer();
//Reading lines of the file and appending them to StringBuffer
while (sc.hasNextLine()) {
buffer.append(sc.nextLine()+System.lineSeparator());
}
String fileContents = buffer.toString();
System.out.println("Contents of the file: "+fileContents);
//closing the Scanner object
sc.close();
String oldLine = "<version>";
String newLine = "<version>1.0.1</version>";
//Replacing the old line with new line
fileContents = fileContents.replaceAll(oldLine, newLine);
//instantiating the FileWriter class
FileWriter writer = new FileWriter(filePath);
System.out.println("");
System.out.println("new data: "+fileContents);
writer.append(fileContents);
writer.flush();
}
}
I suggest that you read file "pom.xml", line by line. If the line read is the line you want to change, then change it otherwise leave it as it is. Then write the line that you read to a temporary file. Once you have read all the lines in file "pom.xml", delete it and rename the temporary file to "pom.xml".
The below code does this.
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
public class OverwriteLine {
public static void main(String[] args) {
Path sourcePath = Path.of("pom.xml");
Path targetPath = Path.of("tmp.xml");
boolean error = false;
try (BufferedReader br = Files.newBufferedReader(sourcePath);
BufferedWriter bw = Files.newBufferedWriter(targetPath,
StandardOpenOption.CREATE,
StandardOpenOption.TRUNCATE_EXISTING,
StandardOpenOption.WRITE)) {
boolean found = false;
String line = br.readLine();
while (line != null) {
if (!found) {
if (line.trim().startsWith("<version>")) {
found = true;
line = line.replace("1.0.0", "1.0.1");
}
}
bw.write(line);
bw.write(System.lineSeparator());
line = br.readLine();
}
}
catch (IOException xIo) {
error = true;
xIo.printStackTrace();
}
if (!error) {
try {
Files.delete(sourcePath);
Files.move(targetPath, sourcePath);
}
catch (IOException xIo) {
xIo.printStackTrace();
}
}
}
}

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.nio.channels.ClosedChannelException HTTP/2 with jetty

I am trying to use HTTP/2 to send an apple notification to my device on production.
I am passing this -Xbootclasspath/p:/home/mohamed/Desktop/alpn-boot-8.1.9.v20160720.jar as a Default VM arguments in eclipse.
Here are the code which i am using now:
public static void pushoNotification() {
try {
// create a low-level Jetty HTTP/2 client
HTTP2Client lowLevelClient = new HTTP2Client();
lowLevelClient.start();
// APNs requires the use of HPACK (header compression for HTTP/2), which prevents repeated header keys and values.
KeyStore ks = KeyStore.getInstance("PKCS12");
// Ensure that the password is the same as the one used later in setKeyStorePassword()
ks.load(PushNotifications.class.getClassLoader().getResourceAsStream("Prod2.p12"), "a12B34".toCharArray());
SslContextFactory ssl = new SslContextFactory(true);
ssl.setKeyStore(ks);
ssl.setKeyStorePassword("a12B34");
// create a high-level Jetty client
HttpClient client = new HttpClient(new HttpClientTransportOverHTTP2(lowLevelClient), ssl);
client.start();
// request-response exchange
ContentResponse response = client.POST("https://api.push.apple.com").path("/3/device/19297dba97212ac6fd16b9cd50f2d86629aed0e49576b2b52ed05086087da802")
.content(new StringContentProvider("{ \"aps\" : { \"alert\" : \"Hello\" } }")).send();
response.toString();
client.stop();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
My dependencies
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.21</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.21</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.http2</groupId>
<artifactId>http2-http-client-transport</artifactId>
<version>9.4.0.M1</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-http</artifactId>
<version>9.4.0.M1</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.http2</groupId>
<artifactId>http2-client</artifactId>
<version>9.4.0.M1</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-client</artifactId>
<version>9.4.0.M1</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-alpn-client</artifactId>
<version>9.4.0.M1</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.mortbay.jetty.alpn</groupId>
<artifactId>alpn-boot</artifactId>
<version>8.1.9.v20160720</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.8.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.8.2</version>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>3.4.1</version>
</dependency>
but when i run this method from main method, it throws java.nio.channels.ClosedChannelException
Also i got this in eclipse console
INFO org.eclipse.jetty.http2.HTTP2Session - Failure while notifying listener org.eclipse.jetty.http2.client.http.HttpClientTransportOverHTTP2$SessionListenerPromise#87eaf9c
Any idea?
Thanks
I am pasting my answer now after about 3 years and 6 month just to help any one get same error, actually i can't recall how i fixed this issue but here are a working code which i am using now...
import java.io.IOException;
import java.io.InputStream;
import java.net.InetSocketAddress;
import java.nio.charset.Charset;
import java.security.KeyStore;
import java.util.Date;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.PostConstruct;
import javax.inject.Singleton;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.CacheControl;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.client.api.ContentResponse;
import org.eclipse.jetty.client.api.Request;
import org.eclipse.jetty.client.util.StringContentProvider;
import org.eclipse.jetty.http2.api.Session;
import org.eclipse.jetty.http2.api.server.ServerSessionListener;
import org.eclipse.jetty.http2.client.HTTP2Client;
import org.eclipse.jetty.http2.client.http.HttpClientTransportOverHTTP2;
import org.eclipse.jetty.util.FuturePromise;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.myproject.path.model.APNSObject;
public void sendIOSNotification(APNSObject apnsObject, List<String> deviceIds, String notificationType) {
HTTP2Client lowLevelClient = null;
HttpClient client = null;
String hostname = null;
InputStream inputStream = null;
try {
lowLevelClient = new HTTP2Client(); // create a low-level Jetty HTTP/2 client
lowLevelClient.start();
// APNs requires the use of HPACK (header compression for HTTP/2), which prevents repeated header keys and values.
KeyStore ks = KeyStore.getInstance(KEYSTORE_TYPE);
inputStream = getClass().getClassLoader().getResourceAsStream(APPLE_CERTIFICATE_PATH);
// Ensure that the password is the same as the one used later in setKeyStorePassword()
ks.load(inputStream, APPLE_CERTIFICATE_PASSWORD.toCharArray());
inputStream.close();
SslContextFactory ssl = new SslContextFactory(true);
ssl.setKeyStore(ks);
ssl.setKeyStorePassword(APPLE_CERTIFICATE_PASSWORD);
FuturePromise<Session> sessionPromise = new FuturePromise<>();
if (notificationType != null && notificationType.trim().equalsIgnoreCase("Development"))
hostname = APPLE_NOTIFICATION_DEVELOPMENT_HOSTNAME;
else
hostname = APPLE_NOTIFICATION_PRODUCTION_HOSTNAME;
lowLevelClient.connect(ssl, new InetSocketAddress(hostname, Integer.parseInt(APPLE_NOTIFICATION_PORT)), new ServerSessionListener.Adapter(), sessionPromise);
// create a high-level Jetty client
client = new HttpClient(new HttpClientTransportOverHTTP2(lowLevelClient), ssl);
client.start();
// logger.info("Start Sending Notification.");
for (String token : deviceIds) {
ObjectMapper mapper = new ObjectMapper();
String fcmJsonObject = mapper.setSerializationInclusion(Include.NON_NULL).setSerializationInclusion(Include.NON_EMPTY).writeValueAsString(apnsObject);
Request request = client.POST("https://" + hostname).timeout(20, TimeUnit.SECONDS).path("/3/device/" + token)
.content(new StringContentProvider(fcmJsonObject, Charset.forName("UTF-8")));
request = request.header("apns-topic", APPLE_APNS_TOPIC);
ContentResponse response = request.send();
// For development mode if it's not passed in parameters
if (response.getStatus() == 400 && !hostname.equals(APPLE_NOTIFICATION_DEVELOPMENT_HOSTNAME)) {
request = client.POST("https://" + APPLE_NOTIFICATION_DEVELOPMENT_HOSTNAME).timeout(20, TimeUnit.SECONDS).path("/3/device/" + token)
.content(new StringContentProvider(fcmJsonObject, Charset.forName("UTF-8")));
request = request.header("apns-topic", APPLE_APNS_TOPIC);
response = request.send();
logger.info("Sending notification to '" + token + "' in debugging mode...");
}
if (response.getStatus() == 200)
logger.info("Date: " + new Date() + " Notification sent successfully to '" + token + "' With Response Status: " + response.getStatus());
else
logger.warning("Sending Notification to token '" + token + "' Failed :( >> Response Status: " + response.getStatus() + "\nReason: " + response.getReason());
}
logger.info("End Sending Notification.");
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (lowLevelClient != null && !lowLevelClient.isStopped())
lowLevelClient.stop();
if (client != null && !client.isStopped())
client.stop();
} catch (Exception e) {
e.printStackTrace();
}
try {
if (inputStream != null)
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
APNSObject.java class
import java.io.Serializable;
public class APNSObject implements Serializable {
// {\"aps\":{\"alert\":{" + messageTitle + "\"body\":\"" + alert + "\"}, \"sound\":\"default\"}" + payload + "}
private static final long serialVersionUID = 1L;
private Aps aps;
private TripBruEntity payload;// Our custom JSON Object
public APNSObject() {
}
public APNSObject(String title, String body, TripBruEntity payload) {
this(title, body, null, payload);
}
public APNSObject(String title, String body, String sound, TripBruEntity payload) {
aps = new Aps(title, body, sound);
this.payload = payload;
}
public Aps getAps() {
return aps;
}
public void setAps(Aps aps) {
this.aps = aps;
}
public TripBruEntity getPayload() {
return payload;
}
public void setPayload(TripBruEntity payload) {
this.payload = payload;
}
static class Aps {
private Alert alert;
private String sound;
public Aps() {
}
public Aps(String title, String body, String sound) {
this.alert = new Alert(title, body);
this.sound = sound == null || sound.isEmpty() ? "default" : sound;
}
public Alert getAlert() {
return alert;
}
public void setAlert(Alert alert) {
this.alert = alert;
}
public String getSound() {
return sound;
}
public void setSound(String sound) {
this.sound = sound;
}
static class Alert {
private String title;
private String body;
public Alert() {
}
public Alert(String title, String body) {
this.title = title;
this.body = body;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getBody() {
return body;
}
public void setBody(String body) {
this.body = body;
}
}
}
}
and here are my configuration file:
APPLE_CERTIFICATE_PATH=/my/apply/certificate/path/so/plz/change/it/Certificates.p12
APPLE_CERTIFICATE_PASSWORD=myPassword(plz change it)
KEYSTORE_TYPE=PKCS12
APPLE_NOTIFICATION_DEVELOPMENT_HOSTNAME=api.development.push.apple.com
APPLE_NOTIFICATION_PRODUCTION_HOSTNAME=api.push.apple.com
APPLE_NOTIFICATION_PORT=2197
APPLE_APNS_TOPIC=MyAPNS_Topic(plz change it)
Last thing, here are jars i used in my project:

Unable to encode series of JPEG images to MPEG video

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!

Categories

Resources