Android Lollipop 中的 FFmpeg 和文件描述符
FFmpeg and file descriptors in Android Lollipop
我打算在 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 选项,但它似乎仅适用于命令行。在此先感谢您的帮助。
The problem is that I would like to extract the complete file name from the file descriptor.
是的,可以通过 Linux 上的小技巧从文件描述符中提取文件的完整路径。每个创建的进程在/proc/[pid]
下都有一个目录,你可以在进程目录/proc/[pid]
下找到进程的相关资源,包括打开的文件描述符。然后打开的文件描述符以/proc/[pid]/fd/[fd_number]
的形式存在,例如/proc/17059/fd/20
。这通常是对真实文件路径的符号link,因此我们可以通过解析符号link.
来获取完整路径
以下是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] != '[=10=]') {
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);
}
我打算在 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 选项,但它似乎仅适用于命令行。在此先感谢您的帮助。
The problem is that I would like to extract the complete file name from the file descriptor.
是的,可以通过 Linux 上的小技巧从文件描述符中提取文件的完整路径。每个创建的进程在/proc/[pid]
下都有一个目录,你可以在进程目录/proc/[pid]
下找到进程的相关资源,包括打开的文件描述符。然后打开的文件描述符以/proc/[pid]/fd/[fd_number]
的形式存在,例如/proc/17059/fd/20
。这通常是对真实文件路径的符号link,因此我们可以通过解析符号link.
以下是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] != '[=10=]') {
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);
}