FFmpeg-no se puede encontrar ExecuteBinaryResponseHandler-Android/Java
(2)
Estoy intentando crear un módulo para react-native que cambie un video en un gif. Tengo poca o ninguna experiencia con android studios / java, ¡pero me encantaría aprender más! Estoy usando esta biblioteca para convertir el video a un gif. Aquí está mi código:
package com.reactlibrary;
import android.widget.Toast;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.github.hiteshsondhi88.libffmpeg.FFmpeg;
public class RNGifMakerModule extends ReactContextBaseJavaModule {
private final ReactApplicationContext reactContext;
public RNGifMakerModule(ReactApplicationContext reactContext) {
super(reactContext);
this.reactContext = reactContext;
}
@Override
public String getName() {
return "RNGifMakerModule";
}
@ReactMethod
public void alert(String message) {
Toast.makeText(getReactApplicationContext(), "Error", Toast.LENGTH_LONG).show();
String[] cmd = {"-i"
, message
, "Image.gif"};
conversion(cmd);
}
public void conversion(String[] cmd) {
FFmpeg ffmpeg = FFmpeg.getInstance(this.reactContext);
try {
// to execute "ffmpeg -version" command you just need to pass "-version"
ffmpeg.execute(cmd, new ExecuteBinaryResponseHandler() {
@Override
public void onStart() {
}
@Override
public void onProgress(String message) {
}
@Override
public void onFailure(String message) {
}
@Override
public void onSuccess(String message) {
}
@Override
public void onFinish() {
}
});
} catch (FFmpegCommandAlreadyRunningException e) {
// Handle if FFmpeg is already running
e.printStackTrace();
}
}
}
Y obtengo este error:
Error:(43, 31) error: cannot find symbol class ExecuteBinaryResponseHandler
Esto parece extraño, porque en la documentación de ffmpeg-android-java dice usar casi exactamente el mismo código.
Generosidad
Se te otorgará la recompensa si puedes encontrar una manera de convertir un video.mp4 en un gif. No necesariamente tiene que usar FFmpeg
, pero su solución debe funcionar con estudios java / android.
Antes que nada, debes iniciar ffmpeg correctamente.
FFmpeg ffmpeg = FFmpeg.getInstance(this.reactContext);
// please add following method after
ffmpeg.loadBinary(new FFmpegLoadBinaryResponseHandler() {
@Override
public void onFailure() {
// probably your device not supported
}
@Override
public void onSuccess() {
// you should init flag here (isLoaded, isReady etc.)
}
Solo después de onSuccess()
puede trabajar con comandos.
Luego, compruebe la siguiente respuesta de LordNeckbeard.
Entonces tu código debería ser algo como esto:
if (isFFmpegLoaded) {
// ffmpeg.execute(commands from link from the answer)
}
No olvide eliminar todos los espacios de la cadena del comando y la palabra "ffmpeg". Para mantener el comando más legible, recomendaré construir un comando como este:
final String[] command = new String[11]; // example of the first command in the answer
command[0] = "-y";
command[1] = "-ss";
command[2] = "30";
command[3] = "-t";
command[4] = "3";
command[5] = "-i";
command[6] = "-t";
command[7] = "filePath";
command[8] = "-vf";
command[9] = "fps=10,scale=320:-1:flags=lanczos,palettegen";
command[10] = "palette.png";
Asegúrate de tener permiso de almacenamiento para trabajar con el archivo por si acaso estás trabajando en almacenamiento externo.
Basado en esta estrategia, ffmpeg me funciona bien. ¡Gracias y buena suerte!
Actualizar:
En realidad, no confío en esta línea:
FFmpeg ffmpeg = FFmpeg.getInstance(this.reactContext);
Parece que ffmpeg tuvo que usar el contexto de la aplicación
En primer lugar, debe usar: Archivo - Invalidar cachés / reiniciar - Invalidar y reiniciar e intentar reimportar ExecuteBinaryResponseHandler
. Si el problema no se ha resuelto, puedes probar el pequeño hack. Dentro de su proyecto, cree el paquete com.github.hiteshsondhi88.libffmpeg
y class:
public class ExecuteBinaryResponseHandler implements FFmpegExecuteResponseHandler {
@Override
public void onSuccess(String message) {
}
@Override
public void onProgress(String message) {
}
@Override
public void onFailure(String message) {
}
@Override
public void onStart() {
}
@Override
public void onFinish() {
}
}
Debe ser como en la imagen:
Luego dentro de su archivo defaultConfig
en el bloque multiDexEnabled true
add multiDexEnabled true
Entonces podrás usar esa clase