Open alexcohn opened 4 years ago
Just curious why this hasn't been merged in. Seems straightforward and needed.
@darrinps there are some good reasons why this was not merged. One, as you noticed, is that this still lacks 64 bit, which makes this solution unsatisfactory for majority of the people who need to target Android Q. Second, people may consider renaming the executable to lib…so to be a dirty trick. Third, this removes a lot of code people had wrote, debugged, and invested into. Not a very nice feeling for a maintainer.
I'm strongly looking forward speedy marge and release, and next one as completely fix.
I would like to target Q as well but cannot until ffmpeg is working with it. Is this code in a fork with a release that can be included?
@pcm2a what is your incentive to target Q? Remember, you can use Q APIs in a project that targets earlier SDK. At any rate, if you don't set min supported SDK to Q, you have to check the availability of these APIs before using them.
@alexcohn just planning ahead. When R is released in 2020 all apps will be forced to target Q I plan on being ready in advance vs rushing to the finish line.
@pcm2a if you think this PR is important, feel free to vote for it.
Waiting for this merge
Besides this fix, for this library to work when targeting Q, we need an option to pass a FileDescriptor
instead of having to pass the file path.
For example, instead of:
String[] command = {"-i", mStringFilePath, "-crf", "18", "-c:v", "libx264", "-c:a", "copy", pathToAppDirectory};
FFmpeg.getInstance(this).execute(command, new ExecuteBinaryResponseHandler()...
We could be given an option to pass a FileDescriptor
, like this:
FileDescriptor fd = getContentResolver().openFileDescriptor(Uri, "r").getFileDescriptor();
//Note that there is no input path provided below
String[] command = {"-crf", "18", "-c:v", "libx264", "-c:a", "copy", pathToAppDirectory};
FFmpeg.getInstance(this).execute(command, fd, new ExecuteBinaryResponseHandler()...
//and when the developer doesn't want to use the FileDescriptor
FFmpeg.getInstance(this).execute(command, null, new ExecuteBinaryResponseHandler()
@HBiSoft Passing FileDescriptor still won't let you work around the scoped storage. You need significant changes on the ffmpeg binary as well, to handle this: pass these file descriptors via Unix sockets.
If you switch to an ffmpeg in-process library solution, e.g. https://github.com/tanersener/mobile-ffmpeg, you can transparently pass your FileDescriptor with the /proc/self/fd/%d trick or pipe:
protocol or use it through a custom AVIOContext.
@alexcohn The owner of FFmpegMediaMetadataRetriever did something similar, have a look here:
You can also have a look at my post on the mobile-ffmpeg library which is related to this - https://github.com/tanersener/mobile-ffmpeg/issues/334#issuecomment-581254355
I believe the owner of this library can easily implement this as well.
@HBiSoft they have their struct State that can handle such URI, that's not how FFmpeg-Android is built.
@alexcohn I was able to get it working on mobile-ffmpeg using the pipe protocol.
What suggestions do you have if we want to achieve the same using this library?
@HBiSoft on the one hand, ffmpeg supports the pipe protocol out-of-the-box, and I believe that the Android port did not damage this functionality. On the other hand, the pipe protocol is not seekable, which may be a significant limitation for some ffmpeg file formats and some applications. I won't propose it as a panacea.
@alexcohn
I tested it with this library and it didn't work. Even if it does, it's not the solution.
This library will either have to be rebuild in a way that excepts Uri
's and can handle them properly or I can't see it working after developers are forced to target API level 29 (which will probably be within the next few months).
@HBiSoft
I tested it with this library and it didn't work.
I am confused. Did you test pipes or the /proc/self/fd
trick?
@alexcohn I tested with pipe ->
String safUriToFFmpegPath(final Uri uri) {
try {
ParcelFileDescriptor parcelFileDescriptor = getContentResolver().openFileDescriptor(uri, "r");
return String.format(Locale.getDefault(), "pipe:%d", parcelFileDescriptor.getFd());
} catch (FileNotFoundException e) {
return "";
}
}
The pipe:
protocol has its own limitations, but in my limited experiments, the /proc/…/fd/…
trick worked as expected. Only note that you cannot use /proc/self/fd
here, you must put the actual Process.myPid()
instead.
@HBiSoft please see https://github.com/alexcohn/FFmpeg-Android/commit/686c4b50653e39c5acb181b0d09cec03e873af5d – for me it resolves the problem with Android Q. I only care about input, but I have no doubt you can follow the same approach to use an output directory out of the app sandbox.
@alexcohn Thank you for your reply.
I have tested the above and I get /proc/4759/fd/70: Permission denied
when selecting from the SD Card.
I see you mentioned this:
Work around the API 29 new [restrictions on use of external storage]
I have tested the above and I get
/proc/4759/fd/70: Permission denied
when selecting from the SD Card.
Yes, it seems to only work for Downloads.
Thanks to @Le-Dinh-Nam #126 comment, I could clean up a bit more. It seems that later platform versions extract all files from lib folder, not filtering by the lib….so pattern, as earlier.
UPDATE no, it does not, see Google Issue. I was forced to revert this change.
Looks good! @Brianvdb Please merge this.
Any update about this?
waiting for this to be merged..
Thanks @alexcohn for merging these changes. When will you release new version of library with this merge?
Any update about this?
Any update about this? When can I expect a new version?
Any update about this?
any update ??
Hi @alexcohn
Any update...? Then please help me.. Thanks(_)
@GauravCreed help you what?
Hi @alexcohn
getting ffmpeg error code 13 in android 10 permission denied in android 10 device. so i am using https://github.com/tanersener/mobile-ffmpeg then problem is apk size increase.
Looks like this isn't going to be merged, is it safe to use the fork directly? @alexcohn Any gotchas? Does this fully work with Android Q/R in the way we expect bravobit/FFmpeg-Android to work?
@AdityaAnand1 I would recommend using (https://github.com/tanersener/mobile-ffmpeg). You get more control over what arch you want to build and you can pass it a Uri
.
Hi, @alexcohn
I am using this library,
https://github.com/tanersener/mobile-ffmpeg implementation 'com.arthenica:mobile-ffmpeg-full:4.2.2.LTS'
this is working on android 10 too , But the problem is i added this library my apk size is increased too much, almost 50mb increased.
Could you please help me with this?
@pratik-tech4 you definitely don't need the 'full' flavor of mobile-ffmpeg: it includes extra libraries that are not part of bravobit. You can make the right choice, or even build a bespoke mixture yourself, only including the external libs that you really need (and maybe revisit your commands to avoid non-necessary external libs, too). Also, if you don't use AAB and don't use split APK, the APK now includes all ABIs. For production, you only care about arm64 and armv7-a as separate binaries.
HI @alexcohn
How about when I am using both audio and video both, i want to add text and image both in video,
implementation 'com.arthenica:mobile-ffmpeg-audio:4.4' implementation 'com.arthenica:mobile-ffmpeg-video:4.4'
it will gives some error like duplicate classes.
Hi @alexcohn
as @GauravCreed said same way i tried but same error.
If i add audio and video version both it gives me same error as @GauravCreed faced. Thats why i am using full version.
I am using it to cut audio then merge it and adding audio to video. So if possible which version i should use to work these functionality.
@GauravCreed, @pratik-tech4: no, you cannot and should not add two ffmpeg-mobile packages.
I would suggest to start with min, and find out what is missing for you. Only if you find that you desperately need more, consider another package. Note that the audio package does contain basic video capabilities, while the video package still provides the essential audio functions.
@GauravCreed, @pratik-tech4 You can build it with custom options like this:
android.sh
look for DISPLAY_HELP=""
and set it to DISPLAY_HELP="yes"
.android.sh
and select run./Users/Hagen/Desktop/mobile-ffmpeg-master/android.sh
/Users/Hagen/Desktop/mobile-ffmpeg-master/android.sh -l --enable-gpl --disable-x86 --disable-x86-64 --enable-x264
android.sh
and set DISPLAY_HELP="yes"
back to DISPLAY_HELP=""
.android.sh
and select run.prebuild
folder.Use the .aar
in your project and do a few tests. If there are missing libraries (in my case zlib
) build the project again and add the missing lib.
By doing this, you have full control over which libs you want based on what you need.
hi, @HBiSoft , @alexcohn
Thank you for your response,
for now i used
implementation 'com.arthenica:mobile-ffmpeg-full:4.4.LTS' in this my apk size is around 74MB.
so, I added ndk filters like below
ndk { abiFilters "armeabi-v7a","arm64-v8a" }
by this two filters apk size is around 48MB.
So now i have one doubt is that
if i make sign apk with these two filters "armeabi-v7a","arm64-v8a", is it approve in play store? as in play store apk must have 64-bit support.
So by these two filter it will approve or no? And it will run in older devices? like which are 32 bit.
Thanks in advance!
@pratik-tech4
Yes it will be approved. armeabi-v7a
is 32bit and arm64-v8a
is 64bit.
I would rather suggest using splits (as shown below) instead of using abiFilter. By splitting the apk`s you will only install the necessary apk. Using abiFilter, you will include all the archs, which increases your apk size unnecessarily.
android.splits {
abi {
enable true
reset()
include 'armeabi-v7a', 'arm64-v8a'
universalApk false
}
}
@pratik-tech4 Yes it will be approved.
armeabi-v7a
is 32bit andarm64-v8a
is 64bit.I would rather suggest using splits (as shown below) instead of using abiFilter. By splitting the apk`s you will only install the necessary apk. Using abiFilter, you will include all the archs, which increases your apk size unnecessarily.
android.splits { abi { enable true reset() include 'armeabi-v7a', 'arm64-v8a' universalApk false } }
@HBiSoft Thanks
by doing this changes both apk is build separately app_armeabi-v7a.apk, app_arm64-v8a.apk. So which one need to upload in play store?
When will you release new version of library with this merge? Please release this as soon as possible. I am waiting for this..
@alexcohn Hey thanks for this PR and it works fine when building and using debug apk,
but as soon as I use a release apk after signing, it doesn't save ffmpeg & ffprobe in /data/app/xxxx/libs folder.
I have tried various methods like enabling/disabling android:extractNativeLibs="true" in App manifest but no luck
However migrating libs to jniLibs folder as lib..ffmpeg.so worked , no idea why.... if anybody does, I am curious
@Shabinder that's true. Android system APK installer extracts only libraries that follow the strict libxxxx.so
naming convention, but makes exception for debug APKs (so that you can embed your debug scripts, like wrap.sh).
When I published this PR, I was not aware of this weird behavior.
When I published this PR, I was not aware of this weird behavior.
Yeah the most weird about it is that there is no flag to keep such resources when building release apk. Anyway thanks for your contributions they helped a lot 👍
At any rate, I strongly recommend you to switch from a poorly supported executable-based solution to a library-based one, e.g. https://github.com/tanersener/ffmpeg-kit.
At any rate, I strongly recommend you to switch from a poorly supported executable-based solution to a library-based one, e.g. https://github.com/tanersener/ffmpeg-kit.
I did went to initially configure ffmpeg-kit, but I needed very much control over ffmpeg-build configuration and wanted to keep the lib size to as low as possible, hence I decided to build my own ffmpeg libs and include them in-app, and as a result Adding FFmpeg just increased just around 2.9 mb in my apk (All 4 arch arm64, x86, arm7, x86_64 ) , I was surprised too. if you want to explore, project is here: https://github.com/Shabinder/SpotiFlyer
Adding FFmpeg-kit as a submodule was not a solution while configuring it custom as It was giving some error that said that produced aar wont be included in parent app(I don't remember the proper wording but there was a limitation) and I didn't wanted to go to the route of maintaining my fork and using mavenCentral as the source
Fixing https://github.com/bravobit/FFmpeg-Android/issues/126