Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How can i use concat function with this lib #16

Open
pavel-corsaghin opened this issue Jun 10, 2017 · 26 comments
Open

How can i use concat function with this lib #16

pavel-corsaghin opened this issue Jun 10, 2017 · 26 comments

Comments

@pavel-corsaghin
Copy link

pavel-corsaghin commented Jun 10, 2017

How can i use concat ffmpeg function to merge two videos with this library. When i use ffmpeg as precompiled binary I was able to it with this code:

LinkedList command = new LinkedList<>();
command.add(mFfmpegPath);
command.add("-f");
command.add("concat");
command.add("-i");
command.add(inputFile);
command.add("-c");
command.add("copy");
command.add("-y");
command.add(outputFile);
return executeFFmpegCommand(command);

Now with your library i try with this code:

String customCommand = "-f concat -c copy";
final Command command = mVideoKit.createCommand()
.overwriteOutput()
.inputPath(tempTextFilePath)
.outputPath(outputPath)
.customCommand(customCommand)
.copyVideoCodec()
.experimentalFlag()
.build();
new AsyncCommandExecutor(command, this).execute();

but it not work and i get error code 3085 in onFailure
Please help me, i would appreciate very much

@pavel-corsaghin
Copy link
Author

where inputPath - a .txt file which contains path of files i want to merge.

@IljaKosynkin
Copy link
Contributor

@pavel-corsaghin
It's not supposed to work that way. If you want to append multiple input paths you should use:
createCommand()
.inputPath(firstPath)
.inputPath(secondPath)
<...>
.build();
Also error code indicates that you have some problem with output file. Did you try to turn on logging and saw what it prints in logs?

@pavel-corsaghin
Copy link
Author

Hi, Thank you. I am trying it. and i have another question. When i try to create my own .so files. I run build_all.sh as bellow:
#!/bin/bash
export DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PARENT="$(dirname "${DIR}")"
export NDK="$(dirname "${PARENT}")"
export PATH="$PATH:$NDK"
export PROJECT_JNI="$(dirname "${NDK}")/JNI/app/jni"
export PROJECT_LIBS="$(dirname "${NDK}")/JNI/app/libs"
#export CONFIGURATION="pass here additional configuration flags if you want to"
#export ADDI_CFLAGS="pass here additional c-flags like include I/path"
#eport ADDI_LDFLAGS="pass here additional flags like include L/path for linker"
export COMMON="--disable-static --disable-programs --disable-doc --enable-shared --enable-protocol=file --enable-small"
./build_armeabi.sh
./build_armeabi-v7a.sh
./build_arm64-v8a.sh
./build_mips.sh
./build_x86.sh

after all done i see only two folder for armeabi and armeabi-v7a in ffmpeg/android folder and i see this in command line
screen shot 2017-06-10 at 18 04 29

@pavel-corsaghin
Copy link
Author

Why i can't get .so files for every platform? what did i do wrong?

@IljaKosynkin
Copy link
Contributor

@pavel-corsaghin
erm, why do you want to use your own libraries? VideoKit supply prepared .so files out of the box.
According to error message - you doesn't have Android.mk file in x86 folder.

@pavel-corsaghin
Copy link
Author

pavel-corsaghin commented Jun 12, 2017

Hi, I want to create my videokit.so file because all classes in your videokit project is not public and i can't extend them for custom ffmpeg command. If i copy all your .so file my app will crash when i try to run "run" method. I think you should make your CommandBuilder class public so people can extend this class. BTW Thank you again for make awesome, useful project. I'm new in ffmpeg and NDK and with your help i have built ffmpeg to my project and use it to cut and merge videos within 3 days.

@IljaKosynkin
Copy link
Contributor

@pavel-corsaghin
Well, it still doesn't explain what kind of functionality VideoKit lacks so you want to create your own .so files. Why don't you use VideoKit directly?

@pavel-corsaghin
Copy link
Author

because i can't concat videos with your libs event i am tried your suggest:
createCommand()
.inputPath(firstPath)
.inputPath(secondPath)
<...>
.build();

but when i created my videokit.so file and use this .txt which contains all input files as one input i was able to concat those videos

@pavel-corsaghin
Copy link
Author

and if i using your code to trim video. It work very slow with long duration. When i using my own code trimming progress very fast:

private void trim(String inputPath, String outputPath, int startTime, int endTime) {
float begin = 1.0f * startTime / 1000;
float end = 1.0f * endTime / 1000;
DebugLogUtils.editorLog("begin: " + begin + " end: " + end);
ArrayList commandList = new ArrayList<>();
commandList.add("-i");
commandList.add(inputPath);
commandList.add("-ss");
commandList.add(begin + "");
commandList.add("-to");
commandList.add(end + "");
commandList.add("-y");
commandList.add("-c");
commandList.add("copy");
commandList.add("-copyts");
commandList.add(outputPath);
final Command command = mVideoKit.createCommand()
.buildCustomCommand(commandList);
new AsyncCommandExecutor(command, this).execute();

// final Command command = mVideoKit.createCommand()
// .overwriteOutput()
// .inputPath(inputPath)
// .outputPath(outputPath)
// .customCommand("-ss " + begin + " -to " + end)
//// .copyVideoCodec()
//// .experimentalFlag()
// .build();
// new AsyncCommandExecutor(command, this).execute();
}

It is reason why i want to custom CommandBuilder.

@IljaKosynkin
Copy link
Contributor

@pavel-corsaghin
Ok, I'm sorta lost point, but I think I get it now.
CommandBuilder is not supposed to be extended - wrap it instead.
Keep in mind - CommandBuilder itself is just a wrapper around CLI of FFmpeg. So if you want to add your command just do it like:
`
class CustomBuilder {
private final CommandBuilder builder;
public CustomBuilder(CommandBuilder builder) {
this.builder = builder;
}

public CustomBuilder yourAwesomeCommand(arguments) {
builder.customCommand("command here");
}

public Command build() {
return builder.build();
}
`
However, if there is strong necessity to provide your own implementation - you can just fork VideoKit, replace .so files with your own ones and write/adjust implementation of CommandBuilder. VideoKit is licensed under LGPL (a long your .so files licensed under LGPL) so you're free to do whatever you want.
As for performance, how did you improve it? I remember I was fighting with it quite a bit and didn't found any good solution for FFmpeg. I ended up switching to MediaCodec and using it for video processing.
Also, did you test your .so files on API > 22? There was a new rule that is working up from Marshmallow - libraries with text relocations will not work. If your .so files has those text relocations and target app have target API level > 22, it will crash.

@pavel-corsaghin
Copy link
Author

pavel-corsaghin commented Jun 12, 2017

Hi, Yes. With your FFmpeg-Development-Kit i have successfully created my .so files (the most important is videokit.so file) then I copied your videokit package into my project and edited the CommandBuilder class. I added that method:

@Override
public Command buildCustomCommand(ArrayList<String> command) {
        String outputPath = command.get(command.size() - 1);
        return new VideoCommand(command, outputPath, videoKit);
}

To speed up video trimming I changed some flags as bellow:

private void trim(String inputPath, String outputPath, int startTime, int endTime) {
        String start = 1.0f * startTime / 1000 + "";
        String end = 1.0f * endTime / 1000 + "";
        DebugLogUtils.editorLog("start: " + start + " end: " + end);

        ArrayList<String> commandList = new ArrayList<>();
        commandList.add("-i");
        commandList.add(inputPath);
        commandList.add("-ss");
        commandList.add(start);
        commandList.add("-to");
        commandList.add(end);
        commandList.add("-y");
        commandList.add("-c");
        commandList.add("copy");
        commandList.add("-copyts");
        commandList.add(outputPath);

        final Command command = mVideoKit.createCommand()
                .buildCustomCommand(commandList);
        new AsyncCommandExecutor(command, this).execute();
}

and it working very fast.

@pavel-corsaghin
Copy link
Author

My app have targetSdkVersion 22 (it because i don't want grant some permission at runtime and i will not change it in the near future). I tested above code in my note 4 (api 22) and in my friend note 5 (api 24) and it work as normal.

@IljaKosynkin
Copy link
Contributor

@pavel-corsaghin ok, so then I would suggest to use your own version (fork of VideoKit).
As I understood you successfully achieved desired functionality with your own implementation?
As for API version, just warning, because I recently ran into such issue.

@pavel-corsaghin
Copy link
Author

Yes, i am able to create my own based on your. Thank you again. About "using MediaCodec for video processing" I am also very interested in this topic because i want to reduce my app size as low as possible. I think if i can use MediaCodec which provided by google i can do it. You can see Du Screen Recorder app, they have very good video editor with apk size <4mb. It awesome :) Are you think they using ffmpeg or other library?

@IljaKosynkin
Copy link
Contributor

@pavel-corsaghin I'm pretty sure they're using MediaCodec since it's embedded into Android from API 18.
I used it for cropping and video trimming back in the days when I was working on video processing in Android. As far as I can recall, FFmpeg was giving time around 1 minute, while with MediaCodec I achieved pretty much the same result within 15-25 seconds. Speed of processing was very important since parallel application on iOS was able to process video files within 15 seconds or so.
I wanted to write blog post about MediaCodec, but haven't much time for it. May be I will try to find time to write it on this week, we will see.

@pavel-corsaghin
Copy link
Author

Hi, I'm really looking forward to that post. Please notify me when you finish writing it.

@IljaKosynkin
Copy link
Contributor

@pavel-corsaghin
I don't know if you're following me:
my main blog is here: https://syllogismobile.wordpress.com
I also duplicate posts on Medium.
I actually didn't expect any attention to my blog and theme of video processing. Since it seems that there are interested people, I will try to write it as soon as possible. Unfortunately, I don't have code (it was taken by client), so I will need a bit of time to write samples.

@pavel-corsaghin
Copy link
Author

Hi, OK. Unfortunately I can not access your blog but I followed you on Medium. And i am waiting for this post.

@pavel-corsaghin
Copy link
Author

Sorry for bothering you again, you tried extract frames with this library, i tried many ways but always failed

@IljaKosynkin
Copy link
Contributor

@pavel-corsaghin
Hm, why cannot you get access to my blog? I thought it's open platform.
Did you try something like this: "ffmpeg -i file.mpg -r 1/1 $filename%03d.bmp"?
in VideoKit it will be like
.inputPath("file.mpg")
.customCommand("-r 1/1 $filename%03d.bmp")
.build();

@pavel-corsaghin
Copy link
Author

Hi, Thank you, i am now able to do this. But can you tell me how can i see log of FFmpeg in my project, now all i see is command option and error code. It is not enough for debug.
screen shot 2017-06-14 at 15 50 14

@IljaKosynkin
Copy link
Contributor

@pavel-corsaghin
Hello.
I also noticed that debug output disappeared for some reason. I will investigate this.

@pavel-corsaghin
Copy link
Author

Hi, I need add text to video so i want to build ffmpeg with flag --enable-libfreetype. But i get error freetype2 not found. I know that i should install freetype first and build ffmpeg with it but i don't know how to do it. Are you ever tried with this flag?

@IljaKosynkin
Copy link
Contributor

@pavel-corsaghin
I was linking FFmpeg with libx264 while ago to speed up processing. In order to link any library to FFmpeg - make sure to get latest sources of that library, build it with NDK and provide correct include paths (for headers and libraries). Note that if you link FFmpeg with any GPL library it automatically will make whole FFmpeg to be licensed under GPL.

@pavel-corsaghin
Copy link
Author

Hi sir! i am tried several hours but i can't build FFmpeg with freetype. This is my build_all.sh file:
#!/bin/bash
export DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PARENT="$(dirname "${DIR}")"
export NDK="$(dirname "${PARENT}")"
export PATH="$PATH:$NDK"
export PROJECT_JNI="$(dirname "${NDK}")/JNI/app/jni"
export PROJECT_LIBS="$(dirname "${NDK}")/JNI/app/libs"
#export CONFIGURATION="pass here additional configuration flags if you want to"
export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig
export ADDI_CFLAGS="-fPIC -I/usr/local/include/freetype2"
export ADDI_LDFLAGS="-Wl,-z,defs -L/usr/local/lib -lfreetype"
export COMMON="--disable-static --disable-programs --disable-doc --enable-shared --enable-protocol=file --enable-pic --enable-small --enable-libfreetype"
./build_armeabi.sh

And i see this error in config.log file:
bin/ld: error: freetype: no archive symbol table (run ranlib)
collect2: error: ld returned 1 exit status
C compiler test failed.

Please tell me what did i do wrong

@rmutter
Copy link

rmutter commented Oct 29, 2017

@pavel-corsaghin did you ever get this to work? I am also trying to rebuild https://github.com/yeti/FFmpeg-Development-Kit with --enable-libfreetype. I've gotten stuck trying to build Freetype for Android and then including it as a dependency.

@IljaKosynkin have you ever attempted this? Appreciate all of your work on this library. The drawtext filter in ffmpeg is just the one additional thing I need to get my current project finished.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants