ffmpeg_cmd.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. #include <jni.h>
  2. #include "ffmpeg/ffmpeg.h"
  3. #include "ffmpeg_jni_define.h"
  4. #define FFMPEG_TAG "FFmpegCmd"
  5. #define INPUT_SIZE (8 * 1024)
  6. #define ALOGI(TAG, FORMAT, ...) __android_log_vprint(ANDROID_LOG_INFO, TAG, FORMAT, ##__VA_ARGS__)
  7. #define ALOGE(TAG, FORMAT, ...) __android_log_vprint(ANDROID_LOG_ERROR, TAG, FORMAT, ##__VA_ARGS__)
  8. int err_count;
  9. JNIEnv *ff_env;
  10. jclass ff_class;
  11. jmethodID ff_method;
  12. jmethodID msg_method;
  13. void log_callback(void *, int, const char *, va_list);
  14. void init(JNIEnv *env) {
  15. ff_env = env;
  16. err_count = 0;
  17. ff_class = (*env)->FindClass(env, "com/cooleshow/ffmpegcmd/FFmpegCmd");
  18. ff_method = (*env)->GetStaticMethodID(env, ff_class, "onProgressCallback", "(III)V");
  19. msg_method = (*env)->GetStaticMethodID(env, ff_class, "onMsgCallback", "(Ljava/lang/String;I)V");
  20. }
  21. FFMPEG_FUNC(jint, handle, jobjectArray commands) {
  22. init(env);
  23. // set the level of log
  24. av_log_set_level(AV_LOG_INFO);
  25. // set the callback of log, and redirect to print android log
  26. av_log_set_callback(log_callback);
  27. int argc = (*env)->GetArrayLength(env, commands);
  28. char **argv = (char **) malloc(argc * sizeof(char *));
  29. int i;
  30. int result;
  31. for (i = 0; i < argc; i++) {
  32. jstring jstr = (jstring) (*env)->GetObjectArrayElement(env, commands, i);
  33. char *temp = (char *) (*env)->GetStringUTFChars(env, jstr, 0);
  34. argv[i] = malloc(INPUT_SIZE);
  35. strcpy(argv[i], temp);
  36. (*env)->ReleaseStringUTFChars(env, jstr, temp);
  37. }
  38. //execute ffmpeg cmd
  39. result = run(argc, argv);
  40. //release memory
  41. for (i = 0; i < argc; i++) {
  42. free(argv[i]);
  43. }
  44. free(argv);
  45. return result;
  46. }
  47. FFMPEG_FUNC(void, cancelTaskJni, jint cancel) {
  48. cancel_task(cancel);
  49. }
  50. void msg_callback(const char *format, va_list args, int level) {
  51. if (ff_env && msg_method) {
  52. char *ff_msg = (char *) malloc(sizeof(char) * INPUT_SIZE);
  53. vsprintf(ff_msg, format, args);
  54. jstring jstr = (*ff_env)->NewStringUTF(ff_env, ff_msg);
  55. (*ff_env)->CallStaticVoidMethod(ff_env, ff_class, msg_method, jstr, level);
  56. free(ff_msg);
  57. }
  58. }
  59. void log_callback(void *ptr, int level, const char *format, va_list args) {
  60. switch (level) {
  61. case AV_LOG_INFO:
  62. ALOGI(FFMPEG_TAG, format, args);
  63. if (format && strncmp("silence", format, 7) == 0) {
  64. msg_callback(format, args, 3);
  65. }
  66. break;
  67. case AV_LOG_ERROR:
  68. ALOGE(FFMPEG_TAG, format, args);
  69. if (err_count < 10) {
  70. err_count++;
  71. msg_callback(format, args, 6);
  72. }
  73. break;
  74. default:
  75. break;
  76. }
  77. }
  78. void progress_callback(int position, int duration, int state) {
  79. if (ff_env && ff_class && ff_method) {
  80. (*ff_env)->CallStaticVoidMethod(ff_env, ff_class, ff_method, position, duration, state);
  81. }
  82. }