bravobit / FFmpeg-Android

FFMpeg/FFprobe compiled for Android
https://bravobit.nl/
MIT License
740 stars 176 forks source link

64bit support? #98

Open moster67 opened 5 years ago

moster67 commented 5 years ago

Hello and many thanks for your ffmpeg library for Android.

After reading about the new 64bit requirement for Android of native libraries, I noted that your library is not stored in Libs but in Assets. Instructions from Google says to verify for the presence of 64bit by looking at the Directory-names. If I unzip, it only contains Arm and x86 directories and does not give an indication if 64 libs is included.

See this: https://developer.android.com/distribute/best-practices/develop/64-bit

However, your readme seems to indicate support for 64bit when it says armv8 (and x86_64).

Can you confirm that your library is OK with Google's new requirements?

Thanks.

yadavkohi commented 5 years ago

you added .so files only or the entire module. Just use the .so files.

alonsd commented 5 years ago

I went to each and every folder and manually pasted them, each in his own place. I did like that for the entire module, maybe that is the mistake? I will try to replace only the .so files and update you.

alonsd commented 5 years ago

worked! thank you very much !

alonsd commented 5 years ago

@yadavkohi I wanted to verify that the actual compressing gives the same results as it did with the 32 bit architecture support. This is unrelated directly to this disscution, but if you do know how do I check the final video compressed size I would be happy to know. After then I will compare it to using the 32 bit solution, before I have implemented your solution for 64 bit and see if the results are the same.

shiv71 commented 5 years ago

@formatBCE I've implemented aar into my project and it's working fine. I want to know is there any way to identify that 64 bit lib is used. Also is there any performance improvement in 64 bit over the 32 bit version in terms of compression time and any other factor.

formatBCE commented 5 years ago

@shiv71 from my research, 64bit binary is 10 to 15% faster on 64bit system, than 32bit. You may use CpuArchHelper static method to find, which architecture was recognised by library. As far as i remember, i made it public. Or you may add any logs to code, since you have it on your PC ;)

yadavkohi commented 5 years ago

You can create emulator with different architecture to check its support.

rafabets commented 5 years ago

@formatBCE I know that's not the subject of the topic, but I didn't find another way to request it. Could you enable registration of "issues" in your fork? Some 64bit users are getting this message "Unknown decoder 'libvpx-vp9'", could you add this encoder/decoder to the compilation, please? "--with-libvpx". Command: -vcodec libvpx-vp9 -i 'filePath.webm' -r 20 'folderPath' -y

formatBCE commented 5 years ago

@rafabets read carefully. I'm not the one who built binaries. I have no such experience nor possibility.

alexcohn commented 5 years ago

Hey guys. Could it be, that, since library is using ffmpeg binary by itself (copy -> run), it should work as is? There's no any pre-compilled .so files, referring to certain architecture. It's just binary executable file, which is launched by app itself, and has no influence in code (and it is in assets folder, btw). So it could be possible, that Google will know nothing about this binary during app publishing.

This is true. The immediate advantage of using 64-bit executables is minor. Slowly, there will appear arm64 devices that will drop backwards compatibility with 32-bit ARM, but I don't expect them in the next 3 years.

Actually, the x86 binaries are a dead weight of ~20Mb for your APK. Intel devices are extremely rare these days. There is an easy fix for that, in build.gradle:

android {
  aaptOptions {
      ignoreAssetsPattern "x86"
  }
}
stanchovy commented 5 years ago

Sorry, there's no simple way - i can't publish that repo to maven central, and i doubt that bravobit will merge pull-request from my fork. I use it as aar lib for our project. Just clone repo into separate Android Studio project, and build it - you'll find aar library in build/outputs folder of main module.

Hey @formatBCE thanks very much for putting together this forked repo.

I'm assuming your implementation and @yadavkohi 's are both different attempts at solving the problem and both are valid, though yours seems a little more convenient because it includes altered code so we don't need to alter code in our own repos in order to use the library -- did I understand that all correctly?

Finally, here are some instructions on how to deploy your work, for those people who are unfamiliar with how to import and deploy an .aar

  1. git clone @formatBCE 's project into your local computer
  2. open the project in Android Studio (I'm using 3.x) and do Build-> Build Project
  3. Look for the resulting aar file: android-ffmpeg/build/outputs/aar/android-ffmpeg-release.aar
  4. Open your project in Android Studio. File -> Project Structure. In the new window, select Modules -> (+) to add a new module. Select the aar file from step 3 and add it.
  5. Adjust your settings.gradle file include line to include ':android-ffmpeg-release'. For example include ':app' ':android-ffmpeg-release'
  6. Go to your app level build.gradle and add the following line to your dependencies { ... } section: compile project(path: ':android-ffmpeg-release', configuration: 'default')
  7. You can now successfully build your project and add the library to your Android code, e.g. import nl.bravobit.ffmpeg.FFmpeg;

Steps 4-7 are explained in more detail here: https://stackoverflow.com/questions/51141190/how-to-add-and-use-an-aar-in-androidstudio-project

Finally, you can verify the whole 64-bit issue by going to Build -> Generate Signed Bundle / APK and building your APK. Then Select Build -> Analyze APK and then selecting your newly generated APK; you should be able to browse and now see a folder structure with /assets/x86_64/ffmpeg and /assets/arm64-v8a/ffmpeg which indicate that you're now including a 64-bit ffmpeg version in your apk that you will eventually be submitting to the Play Store, complying with the new mandate for 64-bit builds.

Hope that helps some people. Updoot if you find this useful so other people see. Do let me know if you see any mistakes above.

PS - @Brianvdb Thank you again for this great library, it'd be really helpful if you could incorporate this 64-bit build; otherwise this library is essentially unusable and will drop off the map which would suck, since the 64-bit binaries are a hard requirement from Google Play Store for all apps going forward.

formatBCE commented 5 years ago

@stanchovy what a great manual! Thank you for putting all info together! I hope our work will serve for guys, struggling with this lib. :)

stanchovy commented 5 years ago

@formatBCE -- you did all the hard work, so thank YOU! Feel free to copy the instructions I wrote into your Github README.txt (if you would like), like since some people may find your forked repo and not know how to install :D

formatBCE commented 5 years ago

@stachovy will do then, thanks!

yadavkohi commented 5 years ago

Sorry, there's no simple way - i can't publish that repo to maven central, and i doubt that bravobit will merge pull-request from my fork. I use it as aar lib for our project. Just clone repo into separate Android Studio project, and build it - you'll find aar library in build/outputs folder of main module.

Hey @formatBCE thanks very much for putting together this forked repo.

I'm assuming your implementation and @yadavkohi 's are both different attempts at solving the problem and both are valid, though yours seems a little more convenient because it includes altered code so we don't need to alter code in our own repos in order to use the library -- did I understand that all correctly?

Finally, here are some instructions on how to deploy your work, for those people who are unfamiliar with how to import and deploy an .aar

  1. git clone @formatBCE 's project into your local computer
  2. open the project in Android Studio (I'm using 3.x) and do Build-> Build Project
  3. Look for the resulting aar file: android-ffmpeg/build/outputs/aar/android-ffmpeg-release.aar
  4. Open your project in Android Studio. File -> Project Structure. In the new window, select Modules -> (+) to add a new module. Select the aar file from step 3 and add it.
  5. Adjust your settings.gradle file include line to include ':android-ffmpeg-release'. For example include ':app' ':android-ffmpeg-release'
  6. Go to your app level build.gradle and add the following line to your dependencies { ... } section: compile project(path: ':android-ffmpeg-release', configuration: 'default')
  7. You can now successfully build your project and add the library to your Android code, e.g. import nl.bravobit.ffmpeg.FFmpeg;

Steps 4-7 are explained in more detail here: https://stackoverflow.com/questions/51141190/how-to-add-and-use-an-aar-in-androidstudio-project

Finally, you can verify the whole 64-bit issue by going to Build -> Generate Signed Bundle / APK and building your APK. Then Select Build -> Analyze APK and then selecting your newly generated APK; you should be able to browse and now see a folder structure with /assets/x86_64/ffmpeg and /assets/arm64-v8a/ffmpeg which indicate that you're now including a 64-bit ffmpeg version in your apk that you will eventually be submitting to the Play Store, complying with the new mandate for 64-bit builds.

Hope that helps some people. Updoot if you find this useful so other people see. Do let me know if you see any mistakes above.

PS - @Brianvdb Thank you again for this great library, it'd be really helpful if you could incorporate this 64-bit build; otherwise this library is essentially unusable and will drop off the map which would suck, since the 64-bit binaries are a hard requirement from Google Play Store for all apps going forward.

@stanchovy I have created ffmpeg binaries for 64-bit architecture support and @formatBCE created a fork branch of repo and put those binaries. so both are the same things.

niallwatchorn commented 5 years ago

@formatBCE -- you did all the hard work, so thank YOU! Feel free to copy the instructions I wrote into your Github README.txt (if you would like), like since some people may find your forked repo and not know how to install :D

do I need to build debug or release or does it matter?

formatBCE commented 5 years ago

@niallwatchorn debug build isn't ready for release to GooglePlay. Also, it will be bigger a bit.

niallwatchorn commented 5 years ago

@formatBCE Thanks for the response. Am getting this error now after following the above steps: Unresolved reference: loadBinary

I have imported the .aar file and setup the gradle file to import it. Do I not need to load the binary like I did in the original FFMPEG library?

Also, doesn't seem to be working:

ffmpeg.loadBinary(object : FFmpegLoadBinaryResponseHandler { override fun onStart() {} override fun onFinish() {} override fun onSuccess() {} override fun onFailure() {} })

and

` ffmpeg.execute(command, object : FFmpegExecuteResponseHandler {

            override fun onStart() {}
            override fun onFinish() {}

            override fun onSuccess(message: String?) {
                buttonExportEditClips?.isEnabled = true
                progressBarExportClip?.visibility = View.GONE

                presenter.onFFMpegSuccess()
            }

            override fun onFailure(message: String?) {}
            override fun onProgress(message: String?) {

            }
        })

`

formatBCE commented 5 years ago

@niallwatchorn no, binaries are in assets folder of aar lib. You may try to include aar as library (into main module libs folder) instead of adding it as separate module.

niallwatchorn commented 5 years ago

@formatBCE Got it, sorry, wasn't checking if it was supported so binary wasn't being copied across. Thanks.

formatBCE commented 5 years ago

@niallwatchorn no problem, good luck with it :)

Arrenign commented 5 years ago

Hi @formatBCE There is a small difference in the altered for 64bit java files on your formatbce and the original repo created by bravobit bravobit, namely the three files CpuArch.java, CpuArchHelper.java, FFmpeg.java. Is it okay to use either || are they the same logic checks??

formatBCE commented 5 years ago

@Arrenign i did not change binaries in any way. Basically, you may replace them by original in project by yourself. :) I've just added 64bit binaries to assets folder (didn't even replace 32bit ones). For correct using that binaries on runtime, i had to change code a bit - basically, original library used 32bit binaries for both 32 and 64 bit architectures. Also, i completely removed ffprobe part from library - it was just useless.

Arrenign commented 5 years ago

@formatBCE Oh thanks dude!! I'll proceed then. :) . Totally forgot you mentioned on earlier comments that you removed ffprobe.

formatBCE commented 5 years ago

@Arrenign no problem )

luifermoron commented 5 years ago

thank you so much for the solution! I am working with App bundle. is there any way to split the Assets folder based on the Architecture that the phone needs?

formatBCE commented 5 years ago

@luifer94 i don't think so. Architecture-based splits can handle "lib" folder, but not an asset. I suspect, the only way to do it it's to have four different builds with manually separated assets. I tried to split assets via custom gradle task, but i'm newbie, and i didn't succeed.

luifermoron commented 5 years ago

thank you for answering. do you know if it is possible to put the files located on assets folder on libs folder? will it work? I am newbie too

formatBCE commented 5 years ago

@luifer94 no, it's not. Assets folder is the only which stays untouched during build, and reachable in runtime for binaries copying to system app folder. That's how this solution works. Other (right) way to do this is create .so libraries for ffmpeg, and put them into libs (with NDK). But in that case, every command should be wrapped by additional java lib method. There's a lot of work to do it. I don't think, that somebody did that already. That's why we use this solution, though it has some consequences...

alexcohn commented 5 years ago

@luifer94 you can look at my pull request that does exactly this (I have not added the 64-bit variant, because I did not have time to test it, but this doesn't require code changes with my solution). The advantage of moving the binaries to libs folder is that this also works on Android Q.

darrinps commented 5 years ago

@alexcohn Do you have plans to add the 64-bit variant soon? Seems to me it would take care of both issues (working with Android Q/10 as the target and the 64 bit support) at the same time.

rafabets commented 5 years ago

Hello guys,

I have created the 64-bit binaries. Please follow the below git repository.

https://github.com/yadavkohi/FFmpeg-64Bit

I have verified that you built with the following libraries:   -libmp3lame -libx264 -libfreetype -libfontconfig

Could you build with the same bravobit libraries? Now i'm getting these messages: "Unknown decoder 'libvpx-vp9'" and "_Unknown encoder 'libfdkaac'" I will be very grateful.

Bravobit build libraries: x264, libpng, freetype2, libmp3lame, libvorbis, libvpx, libopus, fontconfig, libass, fribidi, expat, fdk-aac

alexcohn commented 5 years ago

@darrinps as you see in @rafabets comment, the 64-bit variants built by @yadavkohi cannot exactly replace the 32-bit binaries included in @bravobit solution. But you can easily drop them in if they satisfy your requirements.

Actually, it's enough to put these binaries in the jniLibs folder in your app (renamed to lib..ffmpeg..so), and they will be loaded correctly. No code changes required.

darrinps commented 5 years ago

@alexcohn I appreciate your response here. That followup begs the question though, if the variants built by @yadavkohi don't work as well as the current 32 bit ones already included in FFmpeg-Android, can ones that do work as well be created, and if so, are there plans to get those into it?

We all need good 64 bit versions after all correct? Would think this would be at the top of the list of priorities (although I understand this isn't a "day job" for folks here).

equationl commented 4 years ago

Hey guys, I just found a project from this which support 64bit. But I think the size too big to me, so I just edited a project like this, Use download instead of packaging all binaries. Now it just 20kb.

mati-araujo commented 4 years ago

I am able to generate the APK as expected, but unfortunately both arm64-v8a and x86_64 versions do not contain any 64-bit code.

There is no lib directory when analyzing the APK in Android Studio while the APK armeabi-v7a includes lib / libarm_arch.so.

Any one could solve this problem and publish his app in google play?

alexcohn commented 4 years ago

Where did you find libarm_arch.so? It's not in the latest AAR and not in the source tree.

mati-araujo commented 4 years ago

When I analyze my APK the ffmpeg compilations appears under assets directory and I think they are working but also I find libarm_arch.so under the lib directory but only for 32 bit, and this compilations are being generated because I'm using ffmpeg in my project.

alexcohn commented 4 years ago

This libarm_arch.so may come from a different repo, e.g. https://github.com/WritingMinds/ffmpeg-android-java

afsaredrisy commented 4 years ago

Hi @marsvoltero have you fixed that issue? I am also facing the same issue, having libarm_arch.so in armeabi-v7a and x86 but not in x86_64 and arm64-v8a

alexcohn commented 4 years ago

actually, I would recommend to everybody worried about 64 bit and Android Q to try this different approach: https://github.com/tanersener/mobile-ffmpeg. It works with libffmpeg.so instead of executable, which is better supported by the system, but does have its own caveats.

manikanta1219 commented 4 years ago

Hey guys, I just found a project from this which support 64bit. But I think the size too big to me, so I just edited a project like this, Use download instead of packaging all binaries. Now it just 20kb.

can you tell me clearly how it is possible.

manikanta1219 commented 4 years ago

actually, I would recommend to everybody worried about 64 bit and Android Q to try this different approach: https://github.com/tanersener/mobile-ffmpeg. It works with libffmpeg.so instead of executable, which is better supported by the system, but does have its own caveats.

hii @alexcohn how to use this by removing static binary files from project.can you explain thank you

alexcohn commented 4 years ago

I just edited a project like this, Use download instead of packaging all binaries. Now it just 20kb.

@equationl I am not sure if downloading binaries complies with Play Store policies, but it will definitely not work on Android Q.

equationl commented 4 years ago

I just edited a project like this, Use download instead of packaging all binaries. Now it just 20kb.

@equationl I am not sure if downloading binaries complies with Play Store policies, but it will definitely not work on Android Q.

Actually I already post it to google play,also I'm not sure it complies with Play Store policies. It work well on Android Q, I just run it by Android Virtual Device.

manikanta1219 commented 4 years ago

screen-4

Anybody please tell me how to integrate online music into android app like above image.. Thank you

pankajtalaviya97 commented 4 years ago

https://github.com/WritingMinds/ffmpeg-android is not a 64 bit library

darrinps commented 4 years ago

I just used it in a project running on Android Q on a physical device (Pixel 3XL) and it seems to work fine.

No faster, but it is what it is.

Thanks

On Mon, Nov 11, 2019 at 2:44 AM equationl notifications@github.com wrote:

I just edited a project like this https://github.com/equationl/FFmpeg-Android, Use download instead of packaging all binaries. Now it just 20kb.

@equationl https://github.com/equationl I am not sure if downloading binaries complies with Play Store policies, but it will definitely not work on Android Q.

Actually I already post it to google play,also I'm not sure it complies with Play Store policies. It work well on Android Q, I just run it by Android Virtual Device.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/bravobit/FFmpeg-Android/issues/98?email_source=notifications&email_token=AAKZATD5QRG7EMKVM7UMPW3QTELNXA5CNFSM4G6VOPBKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEDWCLNA#issuecomment-552347060, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAKZATHLB6GRM7LDW3OBODDQTELNXANCNFSM4G6VOPBA .

alexcohn commented 4 years ago

running on Android Q on a physical device

That's cool

pratikbutani commented 4 years ago

I got a solution and My app is published successfully without warning. I have also tested in Firebase Testlab with 5 different devices.

The build.gradle may help you:

apply plugin: 'com.android.application'
// Apply the Firebase Crashlytics plugin.
apply plugin: 'com.google.firebase.crashlytics'

android {
    compileSdkVersion 29
    buildToolsVersion "29.0.2"
    defaultConfig {
        applicationId 'com.example.demo'
        minSdkVersion 21
        targetSdkVersion 28
        multiDexEnabled true
        versionCode 3
        versionName '1.2'
        resConfigs "en"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        vectorDrawables.useSupportLibrary true

        renderscriptTargetApi 19
        renderscriptSupportModeEnabled true
        ndk.abiFilters 'armeabi-v7a','arm64-v8a','x86','x86_64'
    }
    dataBinding {
        enabled true
    }
    buildTypes {
        release {
            minifyEnabled true
            shrinkResources true
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'

            //Other parameters
            debuggable false
            jniDebuggable false
            renderscriptDebuggable false
            //signingConfig playStoreConfig //Add your own signing config
            pseudoLocalesEnabled false
            zipAlignEnabled true
        }
    }
    packagingOptions {
        exclude 'META-INF/DEPENDENCIES'
        exclude 'META-INF/LICENSE'
        exclude 'META-INF/LICENSE.txt'
        exclude 'META-INF/license.txt'
        exclude 'META-INF/NOTICE'
        exclude 'META-INF/NOTICE.txt'
        exclude 'META-INF/notice.txt'
        exclude 'META-INF/ASL2.0'
    }
       aaptOptions {
            ignoreAssetsPattern "!*ffprobe"
            ignoreAssetsPattern "!*ffmpeg"
            ignoreAssetsPattern "!arm"
            ignoreAssetsPattern "!x86"
            additionalParameters "--no-version-vectors"
            cruncherEnabled = false
        }
    compileOptions {
             sourceCompatibility JavaVersion.VERSION_1_8
             targetCompatibility JavaVersion.VERSION_1_8
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'androidx.appcompat:appcompat:1.1.0'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    implementation 'com.google.android.material:material:1.1.0'

    implementation 'com.google.firebase:firebase-firestore:21.4.3'
    implementation 'com.firebaseui:firebase-ui-firestore:6.0.2'
    implementation 'com.google.firebase:firebase-analytics:17.4.0'
    implementation 'com.google.firebase:firebase-messaging:20.1.6'
    implementation 'com.google.firebase:firebase-config:19.1.4'
    implementation 'com.google.firebase:firebase-crashlytics:17.0.0'
    implementation 'com.google.android.gms:play-services-ads:19.1.0'
    implementation 'com.google.firebase:firebase-auth:19.3.1'
    implementation 'com.google.android.gms:play-services-auth:18.0.0'

    implementation 'com.github.bumptech.glide:glide:4.11.0'
    annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'

    annotationProcessor 'androidx.annotation:annotation:1.1.0'

    implementation 'io.github.inflationx:calligraphy3:3.1.1'
    implementation 'io.github.inflationx:viewpump:2.0.3'

    testImplementation 'junit:junit:4.13'
    implementation 'androidx.multidex:multidex:2.0.1'
    androidTestImplementation 'androidx.test:runner:1.2.0'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'

    implementation 'com.squareup.retrofit2:retrofit:2.8.1'
    implementation 'com.squareup.retrofit2:converter-gson:2.8.1'

    implementation 'com.danikula:videocache:2.7.1'
    implementation 'com.github.HamidrezaAmz:MagicalExoPlayer:1.0.14'

    implementation 'com.github.AppIntro:AppIntro:5.1.0'
    implementation 'com.writingminds:FFmpegAndroid:0.3.2'
}

apply plugin: 'com.google.gms.google-services'

I made three changes in that:

  1. Added lines in default config:
                renderscriptTargetApi 19
        renderscriptSupportModeEnabled true
        ndk.abiFilters 'armeabi-v7a','arm64-v8a','x86','x86_64'
  1. added packagingOptions
  2. added aaptOptions

Try. May you will get success.