FFmpeg:在 Android Q 上无法使用文件描述符进行查找

2023-11-27

鉴于公共文件路径通常在具有范围存储的 Android Q 中不可用,我试图弄清楚如何使我的 FFmpeg 音频解码器使用文件描述符,而不将文件复制到我的应用程序的私有目录。

我们可以使用中描述的方法轻松获取文件描述符Android Q 隐私更改,并且可以使用管道协议打开文件描述符,如中所述从可打开的 URI 将本机 fd int 传递到 FFMPEG。但是,使用以下方法无法查找结果av_seek_frame并且使用持续时间成员也无法获得持续时间AVFormatContext.

有没有办法用 FFmpeg 寻找文件描述符并检索持续时间?


可以使用管道协议打开文件描述符,如下所述

我很好奇为什么需要通过管道协议打开文件描述符?sView播放器通过自定义打开文件描述符AVIO上下文,这是可搜索的,至少在较旧的经过测试的 Android 版本上是这样。这是使用自定义 AVIOContext 打开 AVFormatContext 的伪代码。

    int aFileDescriptor = myResMgr->openFileDescriptor(theFileToLoad);
    AVFormatContext* aFormatCtx = avformat_alloc_context();
    StAVIOContext myAvioContext;
    if(!myAvioContext.openFromDescriptor(aFileDescriptor, "rb")) {
       // error
    }

    aFormatCtx->pb = myAvioContext.getAvioContext();
    int avErrCode = avformat_open_input(&aFormatCtx, theFileToLoad, NULL, NULL);

下面尝试提取简化的 StAVIOFileContext 类定义。

//! Wrapper over AVIOContext for passing the custom I/O.
class StAVIOContext {
public:
  //! Main constructor.
  StAVIOContext() {
    const int aBufferSize = 32768;
    unsigned char* aBufferIO = (unsigned char* )av_malloc(aBufferSize + AV_INPUT_BUFFER_PADDING_SIZE);
    AVIOContext* myAvioCtx = avio_alloc_context (aBufferIO, aBufferSize, 0, this, readCallback, writeCallback, seekCallback);
  }

  //! Destructor.
  virtual ~StAVIOContext() {
    close();
    if (myAvioCtx != NULL) { av_free (myAvioCtx); }
  }

  //! Close the file.
  void close() {
    if(myFile != NULL) {
        fclose(myFile);
        myFile = NULL;
    }
  }

  //! Associate a stream with a file that was previously opened for low-level I/O.
  //! The associated file will be automatically closed on destruction.
  bool openFromDescriptor(int theFD, const char* theMode) {
    close();
  #ifdef _WIN32
    myFile = ::_fdopen(theFD, theMode);
  #else
    myFile =  ::fdopen(theFD, theMode);
  #endif
    return myFile != NULL;
  }

  //! Access AVIO context.
  AVIOContext* getAvioContext() const { return myAvioCtx; }

public:

  //! Virtual method for reading the data.
  virtual int read (uint8_t* theBuf,
                    int theBufSize) {
    if(myFile == NULL) { return -1; }

    int aNbRead = (int )::fread(theBuf, 1, theBufSize, myFile);
    if(aNbRead == 0 && feof(myFile) != 0) { return AVERROR_EOF; }
    return aNbRead;
  }

  //! Virtual method for writing the data.
  virtual int write (uint8_t* theBuf,
                     int theBufSize) {
    if(myFile == NULL) { return -1; }
    return (int )::fwrite(theBuf, 1, theBufSize, myFile);
  }

  //! Virtual method for seeking to new position.
  virtual int64_t seek (int64_t theOffset,
                        int theWhence) {
    if(theWhence == AVSEEK_SIZE || myFile == NULL) { return -1; }
  #ifdef _WIN32
    bool isOk = ::_fseeki64(myFile, theOffset, theWhence) == 0;
  #else
    bool isOk =    ::fseeko(myFile, theOffset, theWhence) == 0;
  #endif
    if(!isOk) { return -1; }
  #ifdef _WIN32
    return ::_ftelli64(myFile);
  #else
    return ::ftello(myFile);
  #endif
  }

private:
  //! Callback for reading the data.
  static int readCallback(void* theOpaque,
                          uint8_t* theBuf,
                          int  theBufSize) {
    return theOpaque != NULL
         ? ((StAVIOContext* )theOpaque)->read(theBuf, theBufSize)
         : 0;
  }

  //! Callback for writing the data.
  static int writeCallback(void* theOpaque,
                           uint8_t* theBuf,
                           int theBufSize) {
    return theOpaque != NULL
         ? ((StAVIOContext* )theOpaque)->write(theBuf, theBufSize)
         : 0;
  }

  //! Callback for seeking to new position.
  static int64_t seekCallback(void*   theOpaque,
                              int64_t theOffset,
                              int     theWhence) {
    return theOpaque != NULL
        ? ((StAVIOContext* )theOpaque)->seek(theOffset, theWhence)
        : -1;
  }

protected:
  AVIOContext* myAvioCtx;
  FILE* myFile;
};

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

FFmpeg:在 Android Q 上无法使用文件描述符进行查找 的相关文章

随机推荐

  • 如何使用 azure 服务总线 5.0.0 在 C# azure 函数中手动处理消息完成

    我正在编写一个 Azure 函数来获取 Azure 服务总线中的消息 我想手动处理任何异常 autoCompleteMessages false 无法弄清楚如何将完整或放弃发送回服务队列 尝试过选项1 FunctionName SBQ F1
  • EntityDeploySplit 错误 - Microsoft.Data.Entity.Build.Tasks.dll 丢失

    彻底重新格式化 Windows 并安装 Visual Studio 2013 后 尝试使用数据库优先的实体框架 edmx 文件构建项目会产生以下错误 无法从程序集中加载 EntityDeploySplit 任务 C 程序文件 x86 MSB
  • Haskell 有限场线性代数库

    我正在寻找 Haskell 的有限场线性代数库 就像是FFLAS FFPACK对于 Haskell 来说会很棒 当然 我检查过hmatrix 似乎有一些支持任意矩阵元素类型但我找不到任何与 hmatrix 一起使用的有限域库 当然 我会很感
  • 保存 foreach dopar 循环的多个输出

    我想知道是否 如何可以返回多个输出作为foreach dopar loop 让我们举一个非常简单的例子 假设我想做 2 项操作作为foreach循环 并希望返回或保存每个值的两个操作的结果i 如果只返回一个输出 则很简单 library f
  • 是否有可能在不循环的情况下对ArrayList求和

    是否有可能求和ArrayList不循环 PHP提供sum array 这将给出数组的总和 PHP 代码就像 a array 2 4 6 8 echo sum a array sum a n 我想在 Java 中做同样的事情 List tt
  • 将字典转换为 Numpy 数组

    我正在尝试转换字典 0 0 173 1 342 2 666 3 506 4 94 1 0 13 1 2171 2 1915 3 3075 4 630 2 0 0 1 265 2 5036 3 508 4 11 3 0 0 1 3229 2
  • BTLE(低功耗蓝牙)开发套件 - 必须具有邻近配置文件

    谁能给我指出一个经过测试的低功耗蓝牙开发套件 板 我对接近度配置文件以及与智能手机 尤其是 iPhone 和 Android 设备 以及任何其他具有 BTLE 的设备 的兼容性特别感兴趣 另外 您能告诉我哪些智能手机支持邻近配置文件吗 如果
  • Magento 中保存“特价”的表格在哪里?

    我尝试使用 mySQL 和 php 脚本批量更新 Special price 和 price 我知道包含 price 的表和行 但不知道包含 special price 的表和行 我查看了数据库本身 但仍然没有运气 有任何想法吗 我需要表名
  • android.permission.WRITE_SETTINGS 是否仅授予系统应用程序?

    我们目前正在开发一个应用程序 我们希望在其中更改一些系统设置 当然需要用户许可 android 文档说要执行此操作 您必须添加以下权限
  • 如何使用 C# 对齐 ListView 中单个子项的文本?

    我无法在任何地方找到这个看似简单的主题的答案 是否可以在 WinForms ListView 控件中对齐单个子项的文本 如果是这样 怎么办 我希望同一列中的文本以不同方式对齐 例子 listView1 Columns 1 TextAlign
  • Android Chrome window.onunload

    我正在开发一个 HTML5 应用程序专门针对 Android 和 Chrome 我遇到的问题源于跟踪打开的浏览器选项卡的要求 我通过创建存储在每个选项卡的 sessionStorage 中的唯一 ID 来实现此目的 然后 我通过在每个选项卡
  • 更改了vhost并在CouchDB中重写,无法访问内部API

    我想将我的自定义域映射到设计文档 rewrite Configuration vhosts www myapp com myapp design user rewrite Rewrites from to static browser in
  • HashSet contains() 方法

    我执行下面的代码 发现输出是false import java util Set import java util HashSet public class Name private String first last public Nam
  • 正在运行的 Docker 容器何时会耗尽磁盘空间?

    我已经阅读了很多文档 但我仍然不确定这到底是如何工作的 这有点像 Docker 与 VM 的问题 如果我启动一个带有 2GB 硬盘的虚拟机并用文件填充其磁盘 我知道它会在 2GB 文件后耗尽 Docker 的工作方式相同吗 我想是这样 但从
  • 浮点数转二进制

    我正在尝试将浮点数转换为二进制表示形式 我怎样才能做到这一点 然而 我的目标是不限于 2m 因此我希望能够轻松扩展到任何基础 3 4 8 ecc 到目前为止 我对整数有一个简单的实现 import string LETTER 0123456
  • Django - 如何设置空白= False,必需= False

    我有一个这样的模型 class Message models Model msg models CharField max length 150 我有一个用于插入字段的表格 实际上 django 允许空白 例如 如果我在字段中插入一个空格
  • 如何查询 Npgsql.EntityFrameworkCore 中具有 JSON 数组的列

    Notes 使用 Npsql EntityFrameworkCore PostgreSQL v3 1 4 使用 Npgsql v4 1 3 1 使用代码优先方法 I have the following table called Cars
  • 如何避免键盘打开时jetpack撰写内容上升

    如上所示 当用户打开键盘时 项目列表 文本输入字段和添加按钮都会上升 我希望项目列表保持在原位 而文本输入字段和添加按钮则按原样上升 code 活动 class MainActivity ComponentActivity override
  • 与 SQL Server 建立连接时发生网络相关或特定于实例的错误

    我在 azurewebsites 上有一个简单的 mvc 网站 使用 VS internet 模板 与同一数据中心的 SQL Azure 数据库进行通信 此时的数据库只是做内置的SimpleMembership Provider 我已经从默
  • FFmpeg:在 Android Q 上无法使用文件描述符进行查找

    鉴于公共文件路径通常在具有范围存储的 Android Q 中不可用 我试图弄清楚如何使我的 FFmpeg 音频解码器使用文件描述符 而不将文件复制到我的应用程序的私有目录 我们可以使用中描述的方法轻松获取文件描述符Android Q 隐私更