Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/cmake/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ffmpeg 与要读取的自定义ByteChannel一起使用时,IContainer.open()失败_Ffmpeg_Xuggler_Xuggle - Fatal编程技术网

Ffmpeg 与要读取的自定义ByteChannel一起使用时,IContainer.open()失败

Ffmpeg 与要读取的自定义ByteChannel一起使用时,IContainer.open()失败,ffmpeg,xuggler,xuggle,Ffmpeg,Xuggler,Xuggle,我试图打开一个IContainer对象,该对象正在从自定义输入缓冲区读取,而不是从媒体文件读取。此自定义输入缓冲区的实现如下所示 // Open up the container for READING mInputCStore = new CStore(); IContainerFormat format = IContainerFormat.make(); if (format.setInputFormat("flv") < 0) { throw new IllegalArg

我试图打开一个IContainer对象,该对象正在从自定义输入缓冲区读取,而不是从媒体文件读取。此自定义输入缓冲区的实现如下所示

// Open up the container for READING
mInputCStore = new CStore();

IContainerFormat format = IContainerFormat.make();
if (format.setInputFormat("flv") < 0) {
    throw new IllegalArgumentException("Failed to initialize the input format");
}

// Open up the container
mInputContainer = IContainer.make();
int retval = mInputContainer.open(mPlaybackContainerStore, IContainer.Type.READ, format);       
if (retval < 0) {
    // This little trick converts the non friendly integer return value into  
    // a slightly more friendly object to get a human-readable error name
    IError error = IError.make(retval);
    throw new IllegalArgumentException("could not open input container: " + mPlaybackContainerStore + "; Error: " + error.getDescription());
}
public int read(ByteBuffer buffer) {
    int bytesRead = 0;

    if (buffer == null)
        return 0;

    while (buffer.hasRemaining()) {
        byte b = mBuff.get();
        buffer.put(b);
        bytesRead++;
    }

    return bytesRead;
}
创建和打开容器的代码如下所示

// Open up the container for READING
mInputCStore = new CStore();

IContainerFormat format = IContainerFormat.make();
if (format.setInputFormat("flv") < 0) {
    throw new IllegalArgumentException("Failed to initialize the input format");
}

// Open up the container
mInputContainer = IContainer.make();
int retval = mInputContainer.open(mPlaybackContainerStore, IContainer.Type.READ, format);       
if (retval < 0) {
    // This little trick converts the non friendly integer return value into  
    // a slightly more friendly object to get a human-readable error name
    IError error = IError.make(retval);
    throw new IllegalArgumentException("could not open input container: " + mPlaybackContainerStore + "; Error: " + error.getDescription());
}
public int read(ByteBuffer buffer) {
    int bytesRead = 0;

    if (buffer == null)
        return 0;

    while (buffer.hasRemaining()) {
        byte b = mBuff.get();
        buffer.put(b);
        bytesRead++;
    }

    return bytesRead;
}
写入容器时使用的相同自定义缓冲区正在成功运行。有人能帮我了解一下自定义缓冲区实现中缺少了什么,比如在读取模式下使用它,以及它失败的原因吗

package test;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.ByteChannel;
import java.util.concurrent.ConcurrentLinkedQueue;

public class CStore implements ByteChannel {
    private ConcurrentLinkedQueue<DataChunk> mChunkQueue = null;
    private int mQueueSize = 0;

    // constructor
    public CStore(String type) {
        mQueueSize = 0;
        mChunkQueue = new ConcurrentLinkedQueue<DataChunk>();
        mChunkQueue.clear();
    }

    @Override
    public void close() throws IOException {
        return;
    }

    @Override
    public boolean isOpen() {
        return false;
    }

    @Override
    public int write(ByteBuffer buffer) throws IOException {
        DataChunk chunk = new DataChunk(buffer);
        mChunkQueue.add(chunk);
        mQueueSize += chunk.getLength();
        return 0;
    }

    public int read(ByteBuffer buffer) throws IOException {

        int result = 0;

        DataChunk chunk = mChunkQueue.poll();
        if (chunk != null) {
            buffer = chunk.getBuffer();
            if (buffer != null) {
                result = 0;
            } else {
                result = 1;
            }
        }

        return result;
    }
}

我打开了一个IContainer,用于读取InputStream的自定义实现。为此,您必须手动设置读取文件时通常自动检测到的信息,即:输入格式、编解码器、编解码器详细信息

// Example input stream (raw audio encoded with mulaw).
InputStream input = new FileInputStream("/tmp/test.ul"); 

// Manually set the input format.
IContainerFormat inputFormat = IContainerFormat.make();
inputFormat.setInputFormat("mulaw");

// Open the container.
IContainer container = IContainer.make();
container.open(input, inputFormat);

// Initialize the decoder.
IStreamCoder coder = container.getStream(0).getStreamCoder();
coder.setSampleRate(8000);
coder.setChannels(1);
coder.open(null, null);

现在,您可以像平常一样从容器中读取数据了[即:container.readNextPacketpacket]。

我通过重新实现读取方法解决了这个问题,如下所示

// Open up the container for READING
mInputCStore = new CStore();

IContainerFormat format = IContainerFormat.make();
if (format.setInputFormat("flv") < 0) {
    throw new IllegalArgumentException("Failed to initialize the input format");
}

// Open up the container
mInputContainer = IContainer.make();
int retval = mInputContainer.open(mPlaybackContainerStore, IContainer.Type.READ, format);       
if (retval < 0) {
    // This little trick converts the non friendly integer return value into  
    // a slightly more friendly object to get a human-readable error name
    IError error = IError.make(retval);
    throw new IllegalArgumentException("could not open input container: " + mPlaybackContainerStore + "; Error: " + error.getDescription());
}
public int read(ByteBuffer buffer) {
    int bytesRead = 0;

    if (buffer == null)
        return 0;

    while (buffer.hasRemaining()) {
        byte b = mBuff.get();
        buffer.put(b);
        bytesRead++;
    }

    return bytesRead;
}

请注意,在调用此函数之前,我正在将mChunkQueue转换为ByteBuffer mBuff。不过,仍有清理此类/实现的余地。但它现在已经解决了

有人能帮我解决这个问题吗?这种方法正确吗?我已经有了这个基于文件的输入流,可以从中读取数据。我想做的是考虑一个实时视频流的例子,例如你没有这个数据流的视频呼叫。我正在尝试初始化IContainer以解码代码中尚未到达的视频流。我认为这是正确的。这就是我提供CStore对象的原因,它实现了ByteChannel作为container.open方法的第一个参数。在这一点上,我的代码失败了。然后我计划在实时接收视频流时写入字节通道。对不起,我从来没有使用过字节通道。但是,我假设您需要在打开容器之前定义输入格式。嗨,以前有人尝试过吗?在这种情况下,任何线索或解决方案都会大有帮助。