I am trying to transcode a RTSP stream into an mpeg4 stream over http for use on a webpage in a video tag. I am using vlcj and a 32-bit version of VLC installed locally. I thought I had the right sout settings, but I am getting the following error when finished.
[414c24e8] stream_out_standard stream out error: no mux specified or found by extension
[414c24e8] stream_out_standard stream out error: no mux specified or found by extension
[414d47e8] main stream output error: stream chain failed for `transcode{vcodec=mp4v, vb=1024, acodec=none}:standard{dst=std{access=http,mux=ts,dst=127.0.0.1:5555}}
The sout I am sending in the options argument to the method call is:
:sout=#transcode{vcodec=mp4v, vb=1024, acodec=none}:standard{dst=std{access=http,mux=ts,dst=127.0.0.1:5555}}
What am I doing wrong?
That fixed one of my problems. I still have to work out the various options to pass into the method. Thanks for the help.
Here is the code I am using as a proof of concept for testing purposes and feasibility.
/*
* This Java source file was generated by the Gradle 'init' task.
*/
package aes.video.transcoder;
import uk.co.caprica.vlcj.factory.MediaPlayerFactory;
import uk.co.caprica.vlcj.player.base.MediaPlayer;
public class App {
private static final int EMPTY = 0;
private static final String CAMERA_TEST_URL = "rtsp://xxx.xxx.xxx.xxx:###/media/video1";
private static final char SOUT_SEPERATOR = ':';
private static final char LEFT_BRACE = '{';
private static final char RIGHT_BRACE = '}';
private static final String SOUT="sout=#";
private MediaPlayerFactory factory;
private MediaPlayer mediaPlayer;
private final StringBuilder sb;
public App() {
sb = new StringBuilder(256);
}
public static void main(String[] args) {
App app = new App();
app.transcodeTest(args);
}
public void transcodeTest(String[] args) {
StringBuilder sbl = new StringBuilder(256);
factory = new MediaPlayerFactory();
mediaPlayer = factory.mediaPlayers().newEmbeddedMediaPlayer();
String media = CAMERA_TEST_URL;
String format = formatHttpStream("127.0.0.1", 5555);
String transcode = formatTranscodeString();
sbl.append(SOUT_SEPERATOR);
sbl.append(SOUT);
sbl.append(transcode);
sbl.append(SOUT_SEPERATOR);
sbl.append(format);
String[] options = {sbl.toString()};
System.out.println(options[0]);
mediaPlayer.media().play(CAMERA_TEST_URL, options);
factory.release();
}
private String formatHttpStream(String serverAddress, int serverPort) {
sb.setLength(EMPTY);
// sb.append(":sout=#duplicate{dst=std{access=http,mux=ts,");
sb.append("standard{dst=std{access=http,mux=ts,");
sb.append("dst=");
sb.append(serverAddress);
sb.append(':');
sb.append(serverPort);
sb.append(RIGHT_BRACE);
sb.append(RIGHT_BRACE);
return sb.toString();
}
private String formatTranscodeString() {
sb.setLength(EMPTY);
sb.append("transcode");
sb.append(LEFT_BRACE);
sb.append("vcodec=mp4v,");
sb.append(" vb=1024,");
sb.append(" acodec=none");
sb.append(RIGHT_BRACE);
return sb.toString();
}
}
The Gradle build file is:
/*
* This file was generated by the Gradle 'init' task.
*
* This generated file contains a sample Java application project to get you started.
* For more details take a look at the 'Building Java & JVM projects' chapter in the Gradle
* User Manual available at https://docs.gradle.org/6.8.2/userguide/building_java_projects.html
*/
plugins {
// Apply the application plugin to add support for building a CLI application in Java.
id 'application'
}
repositories {
// Use JCenter for resolving dependencies.
jcenter()
}
dependencies {
// https://mvnrepository.com/artifact/uk.co.caprica/vlcj
implementation 'uk.co.caprica:vlcj:4.7.1'
implementation 'uk.co.caprica:vlcj:4.7.1:sources'
implementation 'uk.co.caprica:vlcj:4.7.1:javadoc'
// Use JUnit test framework.
testImplementation 'junit:junit:4.13'
// This dependency is used by the application.
implementation 'com.google.guava:guava:29.0-jre'
}
application {
// Define the main class for the application.
mainClass = 'aes.video.transcoder.App'
}
This is only a test for proof of concept, and it will not be used in production. I think there is a problem with the sout module string I am using.
The streaming options need to be passed in an array, not a single string with the separator as you have used.
This is a fragment of what you have:
String[] options = {sbl.toString()};
System.out.println(options[0]);
mediaPlayer.media().play(CAMERA_TEST_URL, options);
The initialisation of options
is not correct here.
Where you have SOUT_SEPARATOR
you actually need to pass separate string elements in the array.
I would also recommend looking in the vlcj test sources or the vlcj-examples project at GitHub, there are examples that format transcoding strings and pass them as media options correctly.