从可打开的 URI 将本机 fd int 传递给 FFMPEG

Posted

技术标签:

【中文标题】从可打开的 URI 将本机 fd int 传递给 FFMPEG【英文标题】:Passing a native fd int to FFMPEG from openable URI 【发布时间】:2017-10-04 13:40:17 【问题描述】:

我正在尝试从存储访问框架的CATEGORY_OPENABLE URI 打开文件描述符。我首先尝试使用 sdcard 上的文件,我已经可以使用 _data 列解析为文件路径并打开(我试图避免这样做,而是使用文件描述符)。

我得到这样的原生 int fd:

int fd = getContentResolver().openFileDescriptor(data.getData(), "r").detachFd();

然后在 C++ 中,我试图这样打开它,想法取自How to properly pass an asset FileDescriptor to FFmpeg using JNI in android:

pFormatCtx = avformat_alloc_context();
pFormatCtx->iformat = av_find_input_format("mp3");

char path[50];
sprintf(path, "pipe:%d", fd);

int e;
if(e=(avformat_open_input(&pFormatCtx,path,NULL,NULL)!=0))
    av_strerror(e, path, 50);
    return error;

这会产生来自avformat_open_input 的“未知错误”。如果我使用上面链接到 FileDescriptor 对象的 jni 方法 jniGetFDFromFileDescriptor 来获取 int fd,则会发生同样的事情。如何在不使用文件路径的情况下正确打开带有 FFMPEG 的可打开 URI?

【问题讨论】:

***.com/questions/24701029/… 看起来很相似 @RobertRowntree 我已经在我的问题中链接了它,这就是我试图做的事情的基础。 @SteveM 根据ffmpeg.org/doxygen/2.8/… 错误是由支持库生成的。您可能想查看源代码以找出导致错误的库 @DipenShah 这是迄今为止唯一有用的信息 - 我认为错误是因为我在没有管道协议的情况下构建它。 没有pipe 的构建绝对是导致问题的一个好原因。但是对于许多格式使用pipe: 还不够好,因为 ffmpeg 不启用此协议的搜索,并且某些格式需要搜索才能正确读取和/或写入。为了正确处理来自SAF 的文件,我have defined 自定义了saf: 协议。 【参考方案1】:

@Steve M,也许您从这些帖子中得到了答案:例如: 1.ffmpeg encoding sample wanted?

最后你探索了这个项目。 https://github.com/illuusio/ffmpeg-example

祝你好运! @Stev M

【讨论】:

@Steve M,你可以点击这些链接,拜托:)【参考方案2】:

也许这是一个愚蠢的观察,但您是否尝试替换:

avformat_open_input(&avFormatPtr, "dummyFilename", nullptr, nullptr);

(avformat_open_input(&pFormatCtx,path,NULL,NULL)

替换为:

(avformat_open_input(&pFormatCtx,path,nullptr,nullptr)

?

【讨论】:

ffmpeg 库是纯 C,从纯 C(没有 nullptr 的概念)调用它们是完全合法的。【参考方案3】:

我的项目 (FFmpegMediaMetadataRetriever) 实现了这一点。在此处查看this gist 或full file。

注意:确保您已构建 FFmpeg 并启用了管道协议!

我使用了avformat_open_inputdup() 文件描述符并确保通过以下方式设置偏移量:

 if (state->offset > 0) 
        state->pFormatCtx = avformat_alloc_context();
        state->pFormatCtx->skip_initial_bytes = state->offset;
  

【讨论】:

以上是关于从可打开的 URI 将本机 fd int 传递给 FFMPEG的主要内容,如果未能解决你的问题,请参考以下文章

将数据集合从 .NET 传递给 PL/SQL 包过程或函数?

如何将 URI 传递给意图?

如何将数据从可解码模型传递或实现到 ViewController?

将动态值传递给路由 URI

Nginx 每个位置/将重写的 uri 传递给 proxy_pass

将本机传递参数反应给其他组件