10

I am trying to open a file descriptor from a CATEGORY_OPENABLE URI from the Storage Access Framework. I am first trying with a file on the sdcard, which I can already resolve to a file path using the _data column and open (I am trying to get away from doing this, and use the file descriptor instead).

I get the the native int fd like this:

int fd = getContentResolver().openFileDescriptor(data.getData(), "r").detachFd();

Then in C++, I am trying to open it like this, the idea taken from How to properly pass an asset FileDescriptor to FFmpeg using JNI in Android:

pFormatCtx = avformat_alloc_context();
pFormatCtx->iformat = av_find_input_format("mp3");

char path[50];
sprintf(path, "pipe:%d", fd);

int e;
if(e=(avformat_open_input(&pFormatCtx,path,NULL,NULL)!=0)){
    av_strerror(e, path, 50);
    return error;
}

This yields an "Unknown error" from avformat_open_input. The same thing happens if I use the jni method jniGetFDFromFileDescriptor from the above linked on a FileDescriptor object to get the int fd instead. How can I open an openable URI with FFMPEG correctly without using the file path?

Community
  • 1
  • 1
Steve M
  • 9,296
  • 11
  • 49
  • 98
  • http://stackoverflow.com/questions/24701029/how-to-properly-pass-an-asset-filedescriptor-to-ffmpeg-using-jni-in-android looks similar – Robert Rowntree May 15 '17 at 17:50
  • @RobertRowntree I linked it in my question already, that's what I based what I tried to do on. – Steve M May 15 '17 at 17:51
  • 1
    @SteveM as per https://ffmpeg.org/doxygen/2.8/group__lavu__error.html#ga4ebaa288c7684a26a591c501208910e4 the error is generated from supporting libraries. You might wanna take a look at the source code to figure out which library is causing the error – Dipen Shah May 18 '17 at 20:04
  • 2
    @DipenShah This is the only useful information so far - I think the error is because I built it without the pipe protocol. – Steve M May 22 '17 at 16:52
  • Build without `pipe` is definitely a good cause for the problem. But using `pipe:` for many formats is not good enough, because ffmpeg does not enable seek for this protocol, and some formats need seek for correct read and/or write. To work correctly with files that come from [SAF](https://stackoverflow.com/questions/tagged/storage-access-framework), I [have defined](https://github.com/tanersener/mobile-ffmpeg/pull/440) a custom `saf:` protocol. – Alex Cohn May 30 '20 at 19:30

3 Answers3

3

My project (FFmpegMediaMetadataRetriever) accomplishes this. See this gist or the full file here.

Note: make sure you have built FFmpeg with the pipe protocol enabled!

I used avformat_open_input, dup() the file descriptor and made sure to set the offset via:

 if (state->offset > 0) {
        state->pFormatCtx = avformat_alloc_context();
        state->pFormatCtx->skip_initial_bytes = state->offset;
 } 
William Seemann
  • 3,440
  • 10
  • 44
  • 78
2

@Steve M, may be you got your answer from these posts: such as : 1. ffmpeg encoding sample wanted?

and finally you explore this project . https://github.com/illuusio/ffmpeg-example

Best of luck! @Stev M

Community
  • 1
  • 1
0

Maybe it is a silly observation, but did you try to replace:

avformat_open_input(&avFormatPtr, "dummyFilename", nullptr, nullptr);

(avformat_open_input(&pFormatCtx,path,NULL,NULL)

Replace for:

(avformat_open_input(&pFormatCtx,path,nullptr,nullptr)

?

developer_hatch
  • 15,898
  • 3
  • 42
  • 75
  • ffmpeg libraries are pure C, and calling them from pure C (which does not have a notion of **nullptr**) is entirely legitimate. – Alex Cohn May 30 '20 at 18:12