2013-04-19 3 views
14

Мне удалось скомпилировать halfninja ffmpeg scripts для Android NDK, используя версию NDK r5c. (К сожалению, любая попытка скомпилировать с более ранним NDK вызвала некоторую ошибку), также я не очень хорошо разбираюсь во всем процессе NDK, так что для меня это бит-n-miss.Конкатенировать файлы mp4 в Android с помощью halfninja ffmpeg

Его сценарии компиляции FFmpeg версии N-30996-gf925b24 (конкретный совершить он сделал сценарии для)

Перемещение вперед моего фактического приложения. мне удается обрезать видео без проблем, теперь мне нужно присоединиться/объединить их, но и любой attemp при использовании любых и несколько комбинаций команд из этих 3-х звеньев (link1, link2, link3) порождают ошибки, такие как cat is not valid, > is undefinined, unknown option filter_complex или пытается переопределить некоторые входные файлы.

Кто-нибудь знает, если это возможно и (как это сделать), для объединения/конкатенации видео mp4 (все те же кодеки, размер, качество и т. Д.), Используя компиляцию ffmpeg на платформе Half-Ninja на Android или как скомпилировать/получить ffmpeg для Android с использованием последних исходных кодов?

Я также быстро попробовал mp4Parser без особого успеха.

в конечном счете, я пытался получить этот псевдо-метод работы:

public static File concatenate(String[] inputPaths, String outputPath){ 

    // ... do stuff do generate ffmpeg commands.... 
    VideoKit v = new VideoKit(); 
    v.run(cmds); 

    File f = new File(outputPath); 
    return f; 
} 
+0

мне удалось собрать половину ниндзя проекта, но сейчас я хочу, чтобы сжать большие видео файлы, но в первую очередь я пытался получить звук из звуковой файл, команда неудачного запуска не работает, дает следующую ошибку, 12-20 13: 31: 26.958: W/ActivityManager (290): принудительное удаление ActivityRecord {2c0322f0 uk.co.halfninja.videokit/.MainActivity}: приложение умерло, нет сохраненного состояния какой-либо конкретной причины ?? –

ответ

2

эта последовательность будет кошачьи mp4 на интерфейс командной строки. его со страницы FFmpeg чаво на конкатенации ...

$FFMPEG_HOME/ffmpeg -i gpsclip_seg1.mp4 -vn -f u16le -acodec pcm_s16le -ac 1 -ar 44100 - > temp1.a < /dev/null 
$FFMPEG_HOME/ffmpeg -i gpsclip_seg2.mp4 -vn -f u16le -acodec pcm_s16le -ac 1 -ar 44100 - > temp2.a < /dev/null 
$FFMPEG_HOME/ffmpeg -i gpsclip_seg3.mp4 -vn -f u16le -acodec pcm_s16le -ac 1 -ar 44100 - > temp3.a < /dev/null 
cat temp1.a temp2.a temp3.a > all.a 

$FFMPEG_HOME/ffmpeg -i gpsclip_seg1.mp4 -an -f yuv4mpegpipe - > temp1.v < /dev/null & 
$FFMPEG_HOME/ffmpeg -i gpsclip_seg2.mp4 -an -f yuv4mpegpipe - < /dev/null | tail -n +2 > temp2.v 
$FFMPEG_HOME/ffmpeg -i gpsclip_seg3.mp4 -an -f yuv4mpegpipe - < /dev/null | tail -n +2 > temp3.v 
cat temp1.v temp2.v temp3.v > all.v 

$FFMPEG_HOME/ffmpeg -f u16le -acodec pcm_s16le -ac 1 -ar 44100 -i all.a -f yuv4mpegpipe -i all.v -same_quant -y output.mp4 

я смотрел на «Android.mk» halfninja ... и для тестирования, вы должны быть в состоянии использовать ADB нажать «FFmpeg» исполняемый файл из halfninja сборки to/data/local/... на телефоне. При создании проекта я думаю, что исполняемый файл будет находиться в папке ../output, над папкой JNI в его проекте.

Предполагая, что вы можете получить root на устройстве, вы можете выполнить тестирование на интерфейсе CLI на телефоне, получив оболочку, затем получив root, используя «su», а затем скопируйте выражения cli из ffmpeg/MP4/concat threads, таких как как этот one и запускать их по телефону с выходами в папку, в которой у вас есть доступ.

В тестовом режиме, если вы можете получить желаемый результат, используя шаг за раз в CLI-вызовах, как показано в принятом ответе ссылки, вы можете вернуться на свои интерфейсы JNI, вызвав пакет «videokit» halfninja, той же последовательности команд, которые вы использовали в тесте.

Добавлено Обратите внимание на несколько вызовов ...

Так как вы будете называть, чтобы FFmpeg Lib в несколько раз JNI, вы должны знать об этом issue, которые могут повлиять на многочисленные вызовы в FFmpeg через JNI. Если halfninja еще не выполнил эту проблему, вам, возможно, придется изменить структуру Android.mk, чтобы реализовать библиотеку обертки, о которой говорилось в потоке, чтобы вы могли загружать/выгружать необходимые общие библиотеки между каждым вызовом ffmpeg через JNI ,

андроида и «кошка»

вы должны иметь символическую ссылку в/системы/бен по телефону

lrwxr-xr-x root  shell    2012-07-09 13:02 cat -> toolbox 

, если нет, то попробуйте «BusyBox» установить на телефон, так что вы можете моделировать сценарии на кли по телефону.

+0

привет. Спасибо за попытку, но я не уверен, что вы поняли весь вопрос. У меня нет проблем с компиляцией, установкой или выполнением сборки halffinja ffmpeg. И я легко могу назвать «public native void run (String [] args);» из VideoKit.java, чтобы обрезать видео, например. Вопрос в том, что такое конкретный 'String []' я могу перейти к нему, чтобы слить видео? – Budius

+0

http://stackoverflow.com/questions/12817198/ffmpeg-1-0-android-ndk-r8b U может попробовать это, чтобы построить более свежий ffmpeg на андроиде, содержащий «concat» ... причина, по которой halfninja встроила определенную версию ffmpeg заключается в том, что это бесполезный процесс для переключения в деревья источника diff для ffmpeg и ожидания редактирования ссылок в Android.mk. –

+0

с поправками. ответ –

4

Ответ, предоставленный LordNeckbeard, - это действительно путь.

How to concatenate flv file into one?

Работа с ограничениями

  • не -f concat
  • не -c
  • нет -bsf
ffmpeg -i q.mp4 -vcodec copy -acodec copy -vbsf h264_mp4toannexb q.ts 
ffmpeg -i r.mp4 -vcodec copy -acodec copy -vbsf h264_mp4toannexb r.ts 
ffmpeg -i 'concat:q.ts|r.ts' -vcodec copy -acodec copy -absf aac_adtstoasc qr.mp4 

Joining H264 *without* re-encoding

+0

привет. Я просто попробовал это. '-c' всегда терпит неудачу, я заменил' -vcodec' и '-acodec', затем он дал мне« Unrecognized option bsf », а затем без' bsf' я получил 'av_interleaved_write_frame(): Operation not allowed'. Я попробую комментарий @Robert Rowntree, чтобы использовать этот раздел http://stackoverflow.com/questions/12817198/ffmpeg-1-0-android-ndk-r8b, но мне потребуется некоторое время, потому что 1) это личный проект, который я делаю в свое свободное время, и я перемещаю страну, поэтому свободное время не скоро произойдет, и 2) пока я не очулю голову и не пойму, что происходит со всеми командами. – Budius

+1

привет, Стив, я очень рад, что ты заработал половину/щедрость, так как я мог видеть твои усилия, и я действительно очень ценю это. К сожалению, моя жизнь решила немного перевернуться, потому что я перемещаю страну, и я просто не мог ее протестировать. Но я обязательно проверю и дам вам знать. Также, если/когда мне удастся что-то сделать, я отвечу. – Budius

1

Поскольку версия FFmpeg от Halfninja не может использовать функциональность конкатената, я советую вам обновить библиотеку FFmpeg, по крайней мере, до версии 1.1.

На мой взгляд, у вас есть два варианта:

  • попытаться скомпилировать новую версию FFmpeg с помощью одного из этих двух Compiling FFmpeg on Android направляющих. Тогда вам также может понадобиться более новая версия Android NDK. Это самое простое решение.

  • Или попробуйте реализовать более новую версию FFmpeg в библиотеках halfninja, что сложнее, но тогда вы можете поддерживать почти тот же интерфейс.

0

Привет, у меня есть эта душа. Пользуюсь Mp4parser библиотека

public class Mp4ParserWrapper { 

    public static final String TAG = Mp4ParserWrapper.class.getSimpleName(); 

    public static final int FILE_BUFFER_SIZE = 1024; 

    /** 
    * Appends mp4 audio/video from {@code anotherFileName} to {@code mainFileName}. 
    */ 
    public static boolean append(String mainFileName, String anotherFileName) { 
     boolean rvalue = false; 
     try { 
      File targetFile = new File(mainFileName); 
      File anotherFile = new File(anotherFileName); 
      if (targetFile.exists() && targetFile.length()>0) { 
       String tmpFileName = mainFileName + ".tmp"; 
       //mainfile=vishal0 
       //another file=vishal1 
       //tmpfile=vishal0.tmp 

       append(mainFileName, anotherFileName, tmpFileName); 
       copyFile(tmpFileName, mainFileName); 
       anotherFile.delete(); 
       new File(tmpFileName).delete(); 
       rvalue = true; 
      } else if (targetFile.createNewFile()) { 
       copyFile(anotherFileName, mainFileName); 
       anotherFile.delete(); 
       rvalue = true; 
      } 
     } catch (IOException e) { 
      Log.e(TAG, "Append two mp4 files exception", e); 
     } 
     return rvalue; 
    } 


    public static void copyFile(final String from, final String destination) 
      throws IOException { 
     FileInputStream in = new FileInputStream(from); 
     FileOutputStream out = new FileOutputStream(destination); 
     copy(in, out); 
     in.close(); 
     out.close(); 
    } 

    public static void copy(FileInputStream in, FileOutputStream out) throws IOException { 
     byte[] buf = new byte[FILE_BUFFER_SIZE]; 
     int len; 
     while ((len = in.read(buf)) > 0) { 
      out.write(buf, 0, len); 
     } 
    } 

    public static void append(
      final String firstFile, 
      final String secondFile, 
      final String newFile) throws IOException { 


     final FileInputStream fisOne = new FileInputStream(new File(secondFile)); 
     final FileInputStream fisTwo = new FileInputStream(new File(firstFile)); 
     final FileOutputStream fos = new FileOutputStream(new File(String.format(newFile))); 

     append(fisOne, fisTwo, fos); 

     fisOne.close(); 
     fisTwo.close(); 
     fos.close(); 
    } 



    // FIXME remove deprecated code 
    public static void append(
      final FileInputStream fisOne, 
      final FileInputStream fisTwo, 
      final FileOutputStream out) throws IOException { 

     final Movie movieOne = MovieCreator.build(Channels.newChannel(fisOne)); 
     final Movie movieTwo = MovieCreator.build(Channels.newChannel(fisTwo)); 
     final Movie finalMovie = new Movie(); 

     final List<Track> movieOneTracks = movieOne.getTracks(); 
     final List<Track> movieTwoTracks = movieTwo.getTracks(); 

     for (int i = 0; i <movieOneTracks.size() || i < movieTwoTracks.size(); ++i) { 
      finalMovie.addTrack(new AppendTrack(movieTwoTracks.get(i), movieOneTracks.get(i))); 
     } 

     final IsoFile isoFile = new DefaultMp4Builder().build(finalMovie); 
     isoFile.getBox(out.getChannel()); 
    } 

} 

И взывать с:

Mp4ParserWrapper.append(firstfilename,secondfilename); 
+0

, в какую библиотеку включить этот код для работы – Mavie

Смежные вопросы