Android Lollipop中的FFmpeg和文件描述符

时间:2015-02-08 22:23:09

标签: android linux ffmpeg java-native-interface

我将在Android项目中使用FFmpeg作为JNI库,我知道Kitkat的局限性。由于新发布的Lollipop有可能第三方应用程序访问外部microsd我想利用它。我已阅读this useful question所以我使用ACTION_OPEN_DOCUMENT_TREE意图,用户选择一个文件夹,而不是使用类似的代码来获取文件描述符。然后我将此UNIX文件描述符发送到jni函数。我创建了一个演示,如果我使用这样的东西:

int descriptor = a_file_descriptor;
FILE* fp = fdopen(descriptor , "w");
fprintf(fp, "Hello from Lollipop!");
fclose(fp);
一切都很好。问题是我想从文件描述符中提取完整的文件名。有可能为Linux提供一些技巧,但如果我做一个fopen并尝试fprintf文件中的东西没有任何反应。所以我想我应该使用文件描述符,但如何在FFmpeg中使用它?我读到了pipe选项,但它似乎仅适用于命令行。在此先感谢您的帮助。

1 个答案:

答案 0 :(得分:2)

  

问题是我想从文件描述符中提取完整的文件名。

是的,可以通过Linux上的小技巧从文件描述符中提取文件的完整路径。每个创建的进程都在/proc/[pid]下有一个目录,您可以在进程目录/proc/[pid]下找到有关进程的资源,包括打开的文件描述符。然后打开的文件描述符以/proc/[pid]/fd/[fd_number]的形式存在,例如/proc/17059/fd/20。这通常是指向真实文件路径的符号链接,因此我们可以通过解析符号链接来获取完整路径。

以下是在Linux上运行的演示代码。是的,它可以在Android上的JNI调用中使用。

#include <stdio.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <limits.h>
#include <stdlib.h>

int main(int argc, char **argv) {

    int fd;
    char path[512] = { 0 };
    char* real_path = NULL;

    if ((fd = open("/tmp/test", O_CREAT | O_WRONLY)) == -1) {
        fprintf(stderr, "open fail");
    }

    sprintf(path, "/proc/%d/fd/%d", getpid(), fd);

    if (path[0] != '\0') {
        printf("fd path is %s\n", path);
        real_path = realpath(path, NULL);
        if (real_path != NULL) {
            printf("get full path from fd %s\n", real_path);
            free(real_path);
        }
    }

    exit(EXIT_SUCCESS);
}