2015-02-08 50 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); 
}