I am working on an Android app where I want to create a video from a
list of static images. After doing some search on internet, it made me
realized that using "FFMPEG" is the way to go in getting this thing
done. So I got hold of this site:
https://github.com/guardianproject/android-ffmpeg-java from where I
downloaded the C library and the Java wrapper. I was able to compile the
C library - of course not the way the instruction was laid out - but
still I was able to get "ffmpeg" executable under
/external/android-ffmpeg/ffmpeg directory. I copied that executable in
my current directory and then copied it to a directory under Android
where my app can access it. Then I called the provided Java wrapper but
I am seeing some errors in the log file like follows:
08-13 11:55:37.848: D/FFMPEG(29598): /data/data/com.sample/app_bin/ffmpeg -y -loop 1 -i /storage/emulated/0/usersnapshot/ffmpeg/image%03d.jpg -r 25 -t 2 -qscale 5 /storage/emulated/0/video/snapshot-video.mp4
08-13 11:55:37.898: I/ShellCallback : shellOut()(29598): /data/data/com.sample/app_bin/ffmpeg[1]: syntax error: '(' unexpected
08-13 11:55:37.938: I/ShellCallback : processComplete()(29598): 1
And following is the code snippet (where targetDirectoryForFFMPEG = directory where the images are stored):
FfmpegController ffmpegController = new FfmpegController(this, targetDirectoryForFFMPEG);
String out = videoOutPutFile.getPath();
MediaDesc mediaIn = new MediaDesc();
mediaIn.path = targetDirectoryForFFMPEG+"/image%03d.jpg";
mediaIn.videoFps = "25";
ffmpegController.convertImageToMP4(mediaIn, 2, out,new ShellCallback() {
#Override
public void shellOut(String shellLine) {
Log.i("ShellCallback : shellOut()", shellLine);
}
#Override
public void processComplete(int exitValue) {
Log.i("ShellCallback : processComplete()", exitValue+"");
}
});
Has anybody implemented this before? If yes, can you point me to what am I doing incorrect? I will provide more information if needed.
Do you have root on the device?
Mount '/data' and then enter your same 'ffmpeg' command in the shell and see whether the error is the same.
Try using the shell to test out different command expressions.
Try 'ffmpeg' alone and with just one input file. See whether those commands produce expected output.
My wild guess would be that there is an issue with calling 'ffmpeg.main()' that relates to the details of your build.
Your ffmpeg might not be compiled properly for the arm. I was getting the same error when not using a correctly compiled ffmpeg.
Related
I am trying to find a way to access the environment variables provided by --dart-define inside native iOS and Android code.
Is there any way to do this?
I have tried the guide explained in https://binary-studio.com/2020/06/23/flutter-3/ but that doesn't work as what gets written to the generated .xcconfig is not separated by = but instead by %3D. And I get the error
error: .../ios/Flutter/DEFINEEnvironment.xcconfig:2: expected a ‘=’, but found % (in target 'Runner' from project 'Runner')
The file DEFINEEnvironment.xcconfig gets generated with the following content MY_VAR%3DMY_VALUE instead of MY_VAR=MY_VALUE
UPDATE
This seems to be happening because when reading from the args passed to --dart-define it must be encoding = into %3D. And I don't know how prevent that from happening
It seems that the script has been changed and now includes the necessary code to decode the strings.
The post-action script that needs to be added to Scheme is:
function urldecode() { : "${*//+/ }"; echo "${_//%/\\x}"; }
IFS=',' read -r -a define_items <<< "$DART_DEFINES"
for index in "${!define_items[#]}"
do
define_items[$index]=$(urldecode "${define_items[$index]}");
done
printf "%s\n" "${define_items[#]}" > ${SRCROOT}/Flutter/DEFINEEnvironment.xcconfig
I want write simple application in Python for Android using kivy. Sadly when I start example code I see only splash screen and few second later application finish work. There is a huge problem with debugging because adb on Linux Mint does not detect my device.
Can someone look at my code and tell my why?
To build application I use buildozer. You can also see create_env script to check all dependencies are there.
Best regards.
Draqun
EDIT:
I started debugging my application. Conclusion:
buildozer + python3 + kivy is a bad idea
if I use kivy.uix.button.Button when text attribute is str than I got exception "AttributeError: 'str' object has no attribute 'decode'"
if I use kivy.uix.button.Button when text attribute is bytes than I got exception "ValueError: Button.text accept only str"
It looks like loop with no solution. Some idea when I should report it?
Exception is in .buildozer/android/platform/build/build/python-installs/pad/android/init.py" file so it does not look like kivy and/or buildozer exception.
I've used python-for android tool and faced with the same errors. But in my case, app didn't run at all - crashed from splash screen. Finally, I've found a solution. You can try the same way.
So my pipeline was python3 + python-for-android (p4a tool, python-for-android, from master branch) + kivy (1.10.1)
There is a file "_android.pyx" for android building recipe (full list of avaliable p4a recipes you can see by command p4a recipes). This file is, possibly, used by Buildozer, and exactly used by P4A during APK building procedure. You need to fix it.
You may find it's location in Ubuntu (for example) via:
sudo updatedb
locate _android.pyx
It's path should be something like:
~/.local/lib/python3.6/site-packages/pythonforandroid/recipes/android/src/android/_android.pyx
There should be a string:
python_act = autoclass(JAVA_NAMESPACE.decode('utf-8') + u'.PythonActivity')
so you should change it - something like this:
python_act = autoclass(str(JAVA_NAMESPACE) + u'.PythonActivity'),
or just use some hardcode:
python_act = autoclass("org/kivy/android/PythonActivity")
Or there might be the other decode() usage in sources.
The reason: differences between Python2 and Python3 - the decode() method is usable on the equivalent binary data type in either Python 2 or 3, but it can’t be used by the textual data type consistently between Python 2 and 3 because str in Python 3 doesn’t have the method decode function has different realisation in Python3. More details are here:
pyporting features
issues p4a's github
Hope, it will help you somehow.
I am using ffmpeg to cut video via android, all working fine but only issue come when if the source directory contain space the command is not working by saying file not found
-i /storage/emulated/0/ISave Videos/Br0gv9anKKg.mp4 -acodec copy -vcodec copy -ss 00:00:10 -t 00:00:20 /storage/emulated/0/1547813275685ChunkClip.mp4
file not found is Like"File not found -i /storage/emulated/0/ISave"
But for other path no issue and all works fine only if space is there in file path the issue comes
Cool Question
Its very confusing to solve there type of issues even if we get a solution
The following Link show some fix for handling issues like this
Quoting and escaping
So for the issue you have there is fix Add each word in ffmpeg comments to an LinkedList and then convert to command array so that ffmpeg will execute it
As follows (As per you requirement command)
List<String> cmdList = new LinkedList<>();
cmdList.add("-i");
cmdList.add("/storage/emulated/0/ISave Videos/Br0gv9anKKg.mp4");
cmdList.add("-acodec");
cmdList.add("copy");
cmdList.add("-vcodec");
cmdList.add("copy");
cmdList.add("-ss");
cmdList.add("00:00:10");
cmdList.add("-t");
cmdList.add("00:00:20");
cmdList.add("/storage/emulated/0/1547813275685ChunkClip.mp4");
String[] command = cmdList.toArray(new String[cmdList.size()]);
Hope your issue will be get resolved by this solution
As I'm running an old Python version on android which gives incorrect file sizes for files > 4 GB I tried writing a workaround to get the correct sizes, code:
def getsize_workaround( filename ):
import subprocess as s
output = s.Popen("ls -l " + filename, shell=True, executable="/system/bin/sh", stdout=s.PIPE).communicate()[0]
size = long(re.split(r'\s+', output)[3])
return size
This works well when I try to call it using a simple python script:
print(getsize_workaround(path))
However, when I try to use it in my NZBGet VideoSort script it can't find ls and pops this error at: output = s.Popen("ls -l " + filename, shell=True, executable="/system/bin/sh", stdout=s.PIPE).communicate()[0]-> : /bin/sh: ls: not found. (function is called at line 824, see dropbox link below).
Haven't got a clue why it can't find ls anymore, anyone help is much appreciated. You can find the VideoSort script here: https://db.tt/oM3U5gZR.
PATH variable didn't include the correct directories when run from NZBGet. Fixed by setting os.environ['PATH'] manually. Thanks to abernert for the tip.
also try adding an alias in your bash script for the python version you want to use
alias python=<python version you want to use>
I want to use FFMPEG via COMMAND LINE in my android application.For this purpose:
I have cross-compiled the ffmpeg lib and got the libffmpeg.so
I have stored libffmpeg.so and the ffmpeg exectable in files directory of the my project.
This is the code i am using:
public class FFMPEGActivity extends Activity {
Process p;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String[] cmd =new String[4];
cmd[0]="/data/data/com.example.ffmpegnew/files/libffmpeg";
cmd[1]="-i";
cmd[2]="mnt/sdcard/music/baba.mp4";
cmd[3]="mnt/sdcard/music/outfile.mp4";
p = Runtime.getRuntime().exec(cmd,null, new File("/data/data/com.example.ffmpegnew/files"));
}
catch(Exception e)
{
System.out.println("exception"+e);
}
}
}
This is the exception i am getting:
09-17 13:47:01.679: I/System.out(3752): exceptionjava.io.IOException: Error running exec(). Command: [/data/data/com.example.ffmpegnew/files/libffmpeg.so, -i, mnt/sdcard/music/baba.mp4, mnt/sdcard/music/outfile.mp4] Working Directory: /data/data/com.example.ffmpegnew/files Environment: null
Please tell me how to solve this problem.Thanks in advance.
I think this won't work, unless you somehow manage to compile ffmpeg executable, place it somewhere in the file system , then access it through your native layer. Normally, though, they use libffmpeg API in android such as in Dolphin Player
Your code seems to try to run the library, not the ffmpeg executable. Note that even after fixing your cmd you will need extra tricks to load the libffmpeg.so, because Android loader does not load shared libs from ./
I would suggest to build a statically linked ffmpeg executable to save hassle.
Place ffmpeg and all the files it accesses on the internal card (obtain through context.getDir("", 0).
After you do this, you will be able to run ffmpeg through exec().
Some models, however, will refuse running this too.