kivy / python-for-android

Turn your Python application into an Android APK
https://python-for-android.readthedocs.io
MIT License
8.08k stars 1.8k forks source link

Add ffpyplayer and dependencies recipes for new toolchain. #954

Closed germn closed 6 years ago

germn commented 7 years ago

This PR is about to add recipe for ffpyplayer for new toolchain. https://github.com/kivy/python-for-android/issues/951

Currently it has 3 problems.

1) should_build(self, arch) funcs aren't written for added recipes. 2) ffmpeg recipe should have ['openssl', 'ffpyplayer_codecs'] as opt_depends. But in that case for some reason toolchain tries to build ffmpeg before it's optional dependencies what leads for error. It might be p4a bug or I completely miss something.

Main problem:

3) ffpyplayer recipe itself doesn't work. While looks like it's fine with built ffmpeg it can't find sdl2:

cannot find -lsdl

May be it happens because of sdl2 compiles somehow differently as ffpyplayer need. May be ffpyplayer==v4.0.0 is broken for Android. May be I'm doing something wrong.

If you have any idea how to fix it, you're welcome.

inclement commented 7 years ago

ffpyplayer recipe itself doesn't work. While looks like it's fine with built ffmpeg it can't find sdl2:

Looks like ffpyplayer just does a basic check for an Android build and assumes it's being built with pygame/sdl1, see here. I expect a patch to fix this would be welcome, or a simple short term fix is to add a patch for ffpyplayer in python-for-android. We do this with pyjnius, which also defaults to assuming a pygame build on Android.

germn commented 7 years ago

@inclement, with latest commits ffpyplayer==4.0.0 can be built with new toolchain (and SDL2) successfully.

Only one problem left:

  1. ffmpeg recipe should have ['openssl', 'ffpyplayer_codecs'] as opt_depends. But in that case for some reason toolchain tries to build ffmpeg before it's optional dependencies what leads for error. It might be p4a bug or I completely miss something.

If you'll decide to merge PR, please check it, since, as I said, I'm new with p4a. Thanks.

germn commented 7 years ago

Build order fixed same way as it's done in old toolchain: adding sdl2 as dependency to ffmpeg. This is not correct since actually ffmpeg doesn't dependence of sdl2, but this is question to p4a building recipe order algorithm.

However PR seems to be working and ready to merge.

matham commented 7 years ago

Hey can you test with https://github.com/matham/ffpyplayer/pull/19 to see if that works for both old and new toolchain?

germn commented 7 years ago

@matham, sure, I'll test it today/tomorrow.

There's one thing I want to clarify: while recipe for new toolchain works with v4.0.0, recipe for old toolchain works with v3.2 only (I couldn't make it work with v4.0.0). You're planning to merge update for py4a into both this tags, am I right?

matham commented 7 years ago

I was just planning to merge it into master.

what was the issues with the old toolchain using current master?

germn commented 7 years ago

@matham, I tested py4a.

With new toolchain it works like a charm.

With old toolchain everything compiles fine, but kivy can't use ffpyplayer provider:

[CRITICAL] Video: Unable to find any valuable Video provider.
ffpyplayer - ImportError: dlopen failed: cannot locate symbol "floor" referenced by "core.so"...
File "/home/kivy/my_old_toolchain/build/python-install/lib/python2.7/site-packages/kivy/core/__init__.py", line 59, in core_select_lib
File "/home/kivy/my_old_toolchain/build/python-install/lib/python2.7/site-packages/kivy/core/video/video_ffpyplayer.py", line 50, in <module>
File "/lib/python2.7/site-packages/ffpyplayer/player/__init__.py", line 10, in <module>
File "ffpyplayer/player/frame_queue.pxd", line 25, in init ffpyplayer.player.player (ffpyplayer/player/player.c:10351)
File "ffpyplayer/player/decoder.pxd", line 9, in init ffpyplayer.player.frame_queue (ffpyplayer/player/frame_queue.c:6081)
File "ffpyplayer/player/core.pxd", line 23, in init ffpyplayer.player.decoder (ffpyplayer/player/decoder.c:3737)
matham commented 7 years ago

Ok, merged py4a branch.

That error is weird. The floor function is a standard c function imported from math.h.

matham commented 7 years ago

Can you add the math library to the libraries list and see if it fixes it? Just add 'm' to the list here: https://github.com/matham/ffpyplayer/blob/master/setup.py#L133

germn commented 7 years ago

@matham it works! Thanks.

matham commented 7 years ago

Merged. I guess this and for the old toolchain it should be good once you switch back to using master and remove the patch.

dessant commented 7 years ago

Look @FeralBytes, in case you're interested, i've missed this pr completely. 😊

FeralBytes commented 7 years ago

@germn thank you for this commit; it was recently highlighted to be incredibly important as a core feature for Kivy. Can you confirm this brings video to the SDL2 tool chain? Disregard it clearly does provide video for SDL2. Thanks again.

germn commented 7 years ago

@FeralBytes you're welcome. This PR brings video support (by ffpyplayer Kivy video provider) for new toolchain (SDL2 based) android apps.

FeralBytes commented 7 years ago

@germn I intend to test this tomorrow, confirm I just use your branch of P4A and ensure that ffpyplayer is in the requirements. Does ffpyplayer need to go before or after sdl2 ... or since this recipe is for sdl2/android_new do I just leave sdl2 out of the requirements?

germn commented 7 years ago

or since this recipe is for sdl2/android_new do I just leave sdl2 out of the requirements?

@FeralBytes yes, ffpyplayer uses sdl2 from bootstrap, so you don't need to specify it in requirements. Here's example of requirements line that can be used:

requirements = hostpython2, kivy, ffpyplayer, openssl, ffpyplayer_codecs

FeralBytes commented 7 years ago

@germn I have good news and bad news. The bad news is that I did not have time to test the PR. I am sorry. The good news is that I depend on this PR working so I will get it tested. Hopefully tomorrow. I encountered a new bug while setting things up for the PR, but I have solved the issue; just not in time to also test the PR; before having to leave for work. So tomorrow I should be able to give it a full test and report back my results. Again I am sorry for the delay.

germn commented 7 years ago

@FeralBytes ok! I'm using this PR with Py2 / Android NDK, it would be nice to know if it works with Crystax NDK also.

inclement commented 7 years ago

For anything like this, the CrystaX NDK should work just the same as the normal one.

On 12/02/17 19:44, Gerasimov Mikhail wrote:

@FeralBytes https://github.com/FeralBytes ok! I'm using this PR with Py2 / Android NDK, it would be nice to know if it works with Crystax NDK also.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/kivy/python-for-android/pull/954#issuecomment-279242879, or mute the thread https://github.com/notifications/unsubscribe-auth/ABNQm_9DdwwZK8HY7CyM0wIhccM40DBqks5rb2ElgaJpZM4LIJSN.

FeralBytes commented 7 years ago

requirements = hostpython2, kivy, ffpyplayer, openssl, ffpyplayer_codecs

This seems out of order according to guidance from Tito. Using instead: 'requirements': 'openssl, sdl2, hostpython2, ffpyplayer, ffpyplayer_codecs, transitions, youtube-dl, kivy' The additional requirements are to support my application. First Build Failed see here: Since first build failed now trying: 'requirements': 'openssl, sdl2, python2, ffpyplayer, ffpyplayer_codecs, transitions, youtube-dl, kivy', Same Error. Immediately after ran with 'requirements': 'openssl, sdl2, python2, transitions, youtube-dl, kivy', Program compiles and runs fine with the above requirements and still using your version of P4A=germn@ffpyplayer_new_toolchain. But obviously no way to play ".m4a" files. I will try a Crystax build tomorrow.

FeralBytes commented 7 years ago

Second Failure Log Attached for the Crystax Build. What do you make of the error logs? How should I proceed next?

FeralBytes commented 7 years ago

For this Build I built with Google but changed the requirements like you suggested: 'requirements': 'hostpython2, kivy, ffpyplayer, openssl, ffpyplayer_codecs, transitions, youtube-dl' But it failed too. This final Build I built with Crystax but also changed the requirements likeyou suggested: 'requirements': 'hostpython2, kivy, ffpyplayer, openssl, ffpyplayer_codecs, transitions, youtube-dl' But it failed too. All four Build/Error Logs are located here.

germn commented 7 years ago

@FeralBytes, hello and sorry for late answer. Unfortunately, I can't say what causes errors in your case, I added two missing dependencies for new recipes, but I don't think it'll help. May be problem with sdk version you use, may be with something else. I have no idea, if and how I can fix it in my environment :(

Nevertheless, I have alternative for you (or someone else) who might need to build recipes from this PR. I've just created new VM with Ubuntu recording all steps it took me to get working apk with ffpyplayer support.

With this environment everything should work without errors. Hope it'll be helpful.

1) Install VirtualBox and create VM with Ubuntu 16.04.2. 2) Install all dependencies for buildozer and stuff:

# --- Install basic:
sudo apt-get install python-pip
sudo pip install -U pip

# --- Install p4a:

# http://python-for-android.readthedocs.io/en/latest/quickstart/#installing-dependencies
sudo dpkg --add-architecture i386
sudo apt-get update
sudo apt-get install -y build-essential git zlib1g-dev python2.7 python2.7-dev libncurses5:i386 libstdc++6:i386 zlib1g:i386 openjdk-8-jdk unzip ant ccache

# We need this if we'll clone p4a instead of installing it with pip.
# https://github.com/kivy/python-for-android/blob/master/setup.py
sudo pip install -U appdirs colorama sh Jinja2 six

# Dependencies for ffpyplayer:
sudo apt-get install autoconf libtool

# --- Install buildozer:

# http://buildozer.readthedocs.io/en/latest/installation.html
sudo pip install -U https://github.com/kivy/buildozer/archive/master.zip
sudo pip install -U cython==0.21
sudo dpkg --add-architecture i386
sudo apt-get update
sudo apt-get install build-essential ccache git libncurses5:i386 libstdc++6:i386 libgtk2.0-0:i386 libpangox-1.0-0:i386 libpangoxft-1.0-0:i386 libidn11:i386 python2.7 python2.7-dev openjdk-8-jdk unzip zlib1g-dev zlib1g:i386

3) Download and unpack SDK/NDK/Ant:

# https://dl.google.com/android/repository/android-ndk-r13b-linux-x86_64.zip
# https://dl.google.com/android/android-sdk_r24.4.1-linux.tgz
# http://archive.apache.org/dist/ant/binaries/apache-ant-1.9.4-bin.tar.gz

# I've got "Aidl not found, please install it" error using clean sdk.
# To fix this go to unpacked sdk dir `/home/p4a/android-sdk-linux/tools` run `./android` select all "Tools" and install it.
# Saw solution here: http://globalsoftbay.blogspot.ru/2016/05/solution-aidl-not-found-please-install.html (select all "Tools")

4) Clone kivy and p4a versions you're going to use (p4a should contain this PR), for example:

git clone -b my_kivy https://github.com/germn/kivy my_kivy
git clone -b my_new_toolchain https://github.com/germn/python-for-android my_new_toolchain

5) Edit buildozer.spec to point on dependencies from 3)/4), for example:

requirements.source.kivy = /home/p4a/my_kivy
android.p4a_dir = /home/p4a/my_new_toolchain

android.api = 16
android.sdk = 24.4.1
android.ndk = 13b
android.ndk_path = /home/p4a/android-ndk-r13b
android.sdk_path = /home/p4a/android-sdk-linux
android.ant_path = /home/p4a/apache-ant-1.9.4

6) Edit buildozer.spec to install ffpyplayer, for example:

requirements = python2, android, kivy, ffpyplayer, openssl, ffpyplayer_codecs

7) Run

buildozer android_new debug
germn commented 7 years ago

@inclement anything that stops this PR from being merged?

inclement commented 7 years ago

@germn I don't think so, sorry about the delay, I just haven't had time to review it recently. Following the Kivy release at the weekend we're now moving to do a python-for-android release, and I'll mark this as to-be-merged before that if possible.

rammie commented 6 years ago

Thank you for this pull request. I'm able to build ffmpeg, ffpyplayer and ffpyplayer_codecs using this pull request. However, I've run into a peculiar problem that only occurs with videos that have audio. I'm able to play the same video using the ffpyplayer provider on osx without issue. It has h264 video and aac audio with a mp4 container. Here is the stacktrace from logcat:

[CRITICAL] [ffpyplayer  ] Traceback (most recent call last):
   File "ffpyplayer/player/core.pyx", line 95, in ffpyplayer.player.core.read_thread_enter (ffpyplayer/player/core.c:3499)
   File "ffpyplayer/player/core.pyx", line 2031, in ffpyplayer.player.core.VideoState.read_thread (ffpyplayer/player/core.c:23171)
   File "ffpyplayer/player/core.pyx", line 1806, in ffpyplayer.player.core.VideoState.stream_component_open (ffpyplayer/player/core.c:21072)
 ZeroDivisionError: float division

This is the failing line:

https://github.com/matham/ffpyplayer/blob/master/ffpyplayer/player/core.pyx#L1806

Looking at the source code here,

https://github.com/matham/ffpyplayer/blob/master/ffpyplayer/player/core.pyx#L1684-L1690

It seems like this ZeroDivisionError should never happen, and I'm losing my mind trying to dig deeper. I set the log level to debug for ffpyplayer but nothing more shows up. Any clue about what's going on? I'm hesitant to file this with ffpyplayer since I have the same video working on osx using it as the provider.

matham commented 6 years ago

Can you put print statements to see what the actual values are in case something is wrong with the logger?

germn commented 6 years ago

@rammie hello! Any chance you can provide video file that causes error?

inclement commented 6 years ago

Since the recipes seem good, I've merged them, thanks!

rammie commented 6 years ago

Again, this PR is awesome and thanks for merging it. Also, @matham , @germn thanks for your responses. Here is what I found- my video works fine when I'm not playing other sounds at the same time. The ffpyplayer docs say that doing so requires building ffpyplayer with SDL_Mixer. I modified ffpyplayer's setup.py and this recipe to USE_SDL_MIXER and I got everything to build without issue. I verified that the new build uses SDL Mixer and uses Mix_Volume, but it would still fail when trying to open the audio device in the same exact way.

Some useful notes: This is the line where things go south (opening the audio device): https://github.com/matham/ffpyplayer/blob/master/ffpyplayer/player/core.pyx#L1644

My log statements immediately before it would appear and immediately after this line would not appear as if there were an exception thrown. However log lines one stack frame above would report a return value of 1 for the audio_open function which would then lead to the ZeroDivisionError. This is bizarre and feels like a cython bug of some sort of sython behavior that I don't understand. I tried different cython versions(0.21, 0.23, latest) but that did not help. I did not dig into the generated C code.

I circumvented my issue by using a custom SoundLoader based on Android's MediaPlayer similar to https://github.com/kivy/kivy/blob/master/kivy/core/audio/audio_avplayer.py

I was wondering if it is worthwhile to contribute either of these changes back:

  1. Allow building ffpyplayer with SDL_Mixer. Would require a small PR to ffpyplayer's setup, a change to this recipe to which could be done optionally only if SDL_mixer is also built. This still does not solve the underlying problem of the mysterious ZeroDivision error caused by open_audio_device.
  2. Make a PR to kivy for a MediaPlayer based sound player for android only (similar to the audio_avplayer). This was quite straight forward using pyjnius.
germn commented 6 years ago

@rammie I'm not familiar with this stuff deeply, but if you'll decide to make ffpyplayer related changes, I'm ready to test it.

matham commented 6 years ago

I have been able to reproduce the float division by zero error. It works on ubuntu, but when I compile ffpyplayer and all its deps on centos5, which is very old, I get this error when running a file with audio in the interpreter.

I suspect that it's something to do with the age of the OS, or it could be because I'm compiling sdl2 myself and am possibly missing something. It seems to me like a race condition, but haven't figured out the source.

matham commented 6 years ago

Ok, the ZeroDivisionError should be fixed in master. What happened is that cython inspects the return values of c functions that can raise an exception and based on a specified return value will assume the function raised an exception before returning. I accidentally returned this number which made cython think there was an exception when there wasn't.

Cheaterman commented 4 years ago

Good stuff - needs to be advertised more IMHO. This also works to make SoundFFPY play OGG Vorbis.

EDIT: Correction, it needs to be advertised AT ALL. This doesn't seem to be in any FFPyPlayer documentation yet. :-)

Q2Learn commented 3 years ago

@FeralBytes, hello and sorry for late answer. Unfortunately, I can't say what causes errors in your case, I added two missing dependencies for new recipes, but I don't think it'll help. May be problem with sdk version you use, may be with something else. I have no idea, if and how I can fix it in my environment :(

Nevertheless, I have alternative for you (or someone else) who might need to build recipes from this PR. I've just created new VM with Ubuntu recording all steps it took me to get working apk with ffpyplayer support.

With this environment everything should work without errors. Hope it'll be helpful.

  1. Install VirtualBox and create VM with Ubuntu 16.04.2.
  2. Install all dependencies for buildozer and stuff:
# --- Install basic:
sudo apt-get install python-pip
sudo pip install -U pip

# --- Install p4a:

# http://python-for-android.readthedocs.io/en/latest/quickstart/#installing-dependencies
sudo dpkg --add-architecture i386
sudo apt-get update
sudo apt-get install -y build-essential git zlib1g-dev python2.7 python2.7-dev libncurses5:i386 libstdc++6:i386 zlib1g:i386 openjdk-8-jdk unzip ant ccache

# We need this if we'll clone p4a instead of installing it with pip.
# https://github.com/kivy/python-for-android/blob/master/setup.py
sudo pip install -U appdirs colorama sh Jinja2 six

# Dependencies for ffpyplayer:
sudo apt-get install autoconf libtool

# --- Install buildozer:

# http://buildozer.readthedocs.io/en/latest/installation.html
sudo pip install -U https://github.com/kivy/buildozer/archive/master.zip
sudo pip install -U cython==0.21
sudo dpkg --add-architecture i386
sudo apt-get update
sudo apt-get install build-essential ccache git libncurses5:i386 libstdc++6:i386 libgtk2.0-0:i386 libpangox-1.0-0:i386 libpangoxft-1.0-0:i386 libidn11:i386 python2.7 python2.7-dev openjdk-8-jdk unzip zlib1g-dev zlib1g:i386
  1. Download and unpack SDK/NDK/Ant:
# https://dl.google.com/android/repository/android-ndk-r13b-linux-x86_64.zip
# https://dl.google.com/android/android-sdk_r24.4.1-linux.tgz
# http://archive.apache.org/dist/ant/binaries/apache-ant-1.9.4-bin.tar.gz

# I've got "Aidl not found, please install it" error using clean sdk.
# To fix this go to unpacked sdk dir `/home/p4a/android-sdk-linux/tools` run `./android` select all "Tools" and install it.
# Saw solution here: http://globalsoftbay.blogspot.ru/2016/05/solution-aidl-not-found-please-install.html (select all "Tools")
  1. Clone kivy and p4a versions you're going to use (p4a should contain this PR), for example:
git clone -b my_kivy https://github.com/germn/kivy my_kivy
git clone -b my_new_toolchain https://github.com/germn/python-for-android my_new_toolchain
  1. Edit buildozer.spec to point on dependencies from 3)/4), for example:
requirements.source.kivy = /home/p4a/my_kivy
android.p4a_dir = /home/p4a/my_new_toolchain

android.api = 16
android.sdk = 24.4.1
android.ndk = 13b
android.ndk_path = /home/p4a/android-ndk-r13b
android.sdk_path = /home/p4a/android-sdk-linux
android.ant_path = /home/p4a/apache-ant-1.9.4
  1. Edit buildozer.spec to install ffpyplayer, for example:
requirements = python2, android, kivy, ffpyplayer, openssl, ffpyplayer_codecs
  1. Run
buildozer android_new debug

Hey @germn I am having issues playing video with Ubuntu 18.04, Python 3.8, Kivy 1.11.1, Buildozer 1.8, on Android 9.0 Tablet. It's just loading a black screen. Kivy Camera works though. I tried adding ffpyplayer and ffpyplayer_codecs to the bulldozer requirements but it didn't work. I finally found your merge and I think I need to follow your steps here in quotes. My question is would this work on Ubuntu 18.04 and for Android 9.0? Is it possible to get an updated version of the instructions?

Much appreciated. Thanks.

Q2Learn commented 3 years ago

Good stuff - needs to be advertised more IMHO. This also works to make SoundFFPY play OGG Vorbis.

EDIT: Correction, it needs to be advertised AT ALL. This doesn't seem to be in any FFPyPlayer documentation yet. :-)

Absolutely! It took me a week of Kivy Video troubles to find this and I am now hopeful this will get it going.