1

我正在尝试通过 http 将 RTSP 流转码为 mpeg4 流,以便在视频标签中的网页上使用。我正在使用 vlcj 和本地安装的 32 位版本的 VLC。我以为我的 sout 设置正确,但完成后出现以下错误。

[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}}

我在方法调用的 options 参数中发送的 sout 是:

:sout=#transcode{vcodec=mp4v, vb=1024, acodec=none}:standard{dst=std{access=http,mux=ts,dst=127.0.0.1:5555}}

我究竟做错了什么?


2021 年 12 月 30 日更新

这解决了我的一个问题。我仍然需要制定各种选项才能传递给该方法。谢谢您的帮助。


2021 年 12 月 29 日更新:

这是我用作测试目的和可行性的概念证明的代码。

/*
 * 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();
    }
}

Gradle 构建文件是:

/*
 * 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'
}

这只是概念验证的测试,不会在生产中使用。我认为我正在使用的 sout 模块字符串存在问题。

4

1 回答 1

0

流选项需要在数组中传递,而不是像您使用的那样带有分隔符的单个字符串。

这是你所拥有的一个片段:

String[] options = {sbl.toString()};
System.out.println(options[0]);
mediaPlayer.media().play(CAMERA_TEST_URL, options);

这里的初始化options不正确。

SOUT_SEPARATOR实际上需要在数组中传递单独的字符串元素。

我还建议查看 GitHub 上的 vlcj 测试源或 vlcj-examples 项目,有一些示例可以格式化转码字符串并将它们作为媒体选项正确传递。

于 2021-12-29T17:50:20.897 回答