2015-02-08 43 views
0

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

int descriptor = a_file_descriptor; 
FILE* fp = fdopen(descriptor , "w"); 
fprintf(fp, "Hello from Lollipop!"); 
fclose(fp); 

一切都很好。问题是我想从文件描述符中提取完整的文件名。使用Linux的一些技巧是可能的,但如果我做了一个fopen并尝试在文件中打印某些东西,则什么都不会发生。所以我想我应该使用文件描述符,但如何使用它与FFmpeg?我读了关于pipe选项,但它似乎只用于命令行。先谢谢您的帮助。

回答

1

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

是的,可以从文件描述符中提取一个文件的完整路径,在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); 
}