2010-09-10 10 views
40

Wie kann ich eine Videodatei aus einer Reihe von Bildern/Fotos auf Android erstellen? Kann dies mit dem aktuellen SDK getan werden? oder brauche ich eine Codec-Bibliothek?Eine Reihe von Bildern in ein Video kodieren

+0

Ich schlage vor, diese Frage in [Stackoverflow für Multimedia System] fragen (http://area51.stackexchange.com/proposals/91149/multimedia-systems) – Hamed

Antwort

11

Ich stimme Mark zu. Unter den C/C++ - Bibliotheken sind ffmpeg here oder X264 here. Ich muss sagen, ich habe sie nicht gefunden oder das Android NDK einfach zu bedienen, aber das ist wahrscheinlich, weil ich nicht wirklich viel über C/C++ und JNI weiß. Wenn Sie an dieser Route interessiert sind, dann hat die kostenlose RockPlayer App für Android die vorgefertigten Bibliotheken von ffmpeg bereit für den Einsatz auf Android. Sie behaupten, dass diese Bibliotheken nur LGPL-Komponenten verwenden, aber Sie müssen sich auf diese Weise überzeugen, denke ich. In Bezug auf Java gibt es einen Port (von Arten) von ffmpeg, der, wie nicht anders zu erwarten, jffmpeg ist, auf den Sie zugreifen können, aber er ruft immer noch zu einem großen Teil des bestehenden ffmpeg-Frameworks auf, so dass Sie wieder im NDK-Land sind. Es ist möglich, eine Reihe von Bildern mit dem Java Media Framework (JMF) in Video zu konvertieren, aber es hat die folgenden Nachteile:

  • Begrenzte Anzahl von Videoformaten.
  • Erzeugt keine Videos, die auf den meisten (wenn nicht allen) Android-Telefonen, z. H264 oder MPEG4.
  • Der JMF-Code ist jetzt ziemlich alt, ist seit langer Zeit nicht mehr fortgeschritten, ist aufgebläht und nicht gut strukturiert, so dass möglicherweise zusätzliche Java-Abhängigkeiten vorhanden sind, die nicht in Android verpackt sind.
  • Eine andere Option, die ich gesehen habe, ist Adobe Air, aber es ist eine 17MB Nutzlast, über die sich einige Benutzer beschweren.

    Es gibt viele andere Fragen hier zu Stack Overflow in Bezug auf ffmpeg und Android NDK.

    Viel Glück mit dem Projekt.

    +1

    Wie kann ich das mit Adobe Air machen? –

    +0

    @Ilya_Gazman Tut mir leid, ich habe keine Erfahrung mit Adobe Air. Bei der Recherche zu diesem Thema bin ich auf einige Hinweise gestoßen. –

    +0

    Ich sehe. Ich denke nicht, dass das mit ihnen möglich ist. Ich kenne keine Luftbibliothek, die das kann. –

    4

    Es gibt keine integrierte Unterstützung dafür. Sie müssten entweder einen Java-Quellcode finden, der das tut, was Sie brauchen, oder einen C/C++ - Code, den Sie in eine Bibliothek umwandeln und über das NDK verwenden können. Wenn das Endziel darin besteht, dass sich das Video auf einem Server befindet, laden Sie die Bilder/Fotos hoch und lassen Sie das Video vom Server erstellen.

    4

    ffmpeg ist Ihr Rettungs-Ranger. Sie können den FFMPEG-Anschluss für Android herunterladen. Weitere Informationen finden Sie in der Frage FFmpeg on Android.

    Der Port unterstützt fast alles, was Sie jemals brauchen werden, einschließlich der Formate - Eingabeformate wie GIF, JPG, PNG, BMP usw. und Ausgabeformate wie AVI, MP4 (Container) mit vielen Codecs.

    +8

    In meiner gesamten Suche konnte ich keinen ffmpeg Port für Android finden. Es schien mir, dass Sie ffmpeg herunterladen, .config darauf ausführen mussten (für das Zielbetriebssystem und einschließlich der von Ihnen gewünschten Codecs) und es dann in eine gemeinsam genutzte Bibliothek einbauen, in die Sie dann einen JNI-Wrapper schreiben mussten - vorausgesetzt, Sie haben auf dem Weg keine Fehler bekommen. Vielleicht wären Sie gut genug, um einen Link zum Download dieses ffmpeg-Ports zu teilen? –

    1

    Sie können eine kostenlose Open-Source-Bibliothek namens JCodec (http://jcodec.org) verwenden, die Java-Implementierungen einiger beliebter Videoformate und Codecs enthält, einschließlich: H.264 (AVC), MPEG 1/2, Apple ProRes, JPEG, MP4 (ISO BMF), MPEG PS, MPEG TS, Matroska.
    können Sie verwenden, um die KORRIGIERT Klasse unterhalb nutzt JCodec Low-Level-API:

    public class SequenceEncoder { 
        private SeekableByteChannel ch; 
        private Picture toEncode; 
        private RgbToYuv420 transform; 
        private H264Encoder encoder; 
        private ArrayList<ByteBuffer> spsList; 
        private ArrayList<ByteBuffer> ppsList; 
        private CompressedTrack outTrack; 
        private ByteBuffer _out; 
        private int frameNo; 
        private MP4Muxer muxer; 
    
        public SequenceEncoder(File out) throws IOException { 
         this.ch = NIOUtils.writableFileChannel(out); 
    
         // Transform to convert between RGB and YUV 
         transform = new RgbToYuv420(0, 0); 
    
         // Muxer that will store the encoded frames 
         muxer = new MP4Muxer(ch, Brand.MP4); 
    
         // Add video track to muxer 
         outTrack = muxer.addTrackForCompressed(TrackType.VIDEO, 25); 
    
         // Allocate a buffer big enough to hold output frames 
         _out = ByteBuffer.allocate(1920 * 1080 * 6); 
    
         // Create an instance of encoder 
         encoder = new H264Encoder(); 
    
         // Encoder extra data (SPS, PPS) to be stored in a special place of 
         // MP4 
         spsList = new ArrayList<ByteBuffer>(); 
         ppsList = new ArrayList<ByteBuffer>(); 
    
        } 
    
        public void encodeImage(BufferedImage bi) throws IOException { 
         if (toEncode == null) { 
          toEncode = Picture.create(bi.getWidth(), bi.getHeight(), ColorSpace.YUV420); 
         } 
    
         // Perform conversion 
         for (int i = 0; i < 3; i++) 
          Arrays.fill(toEncode.getData()[i], 0); 
         transform.transform(AWTUtil.fromBufferedImage(bi), toEncode); 
    
         // Encode image into H.264 frame, the result is stored in '_out' buffer 
         _out.clear(); 
         ByteBuffer result = encoder.encodeFrame(_out, toEncode); 
    
         // Based on the frame above form correct MP4 packet 
         spsList.clear(); 
         ppsList.clear(); 
         H264Utils.encodeMOVPacket(result, spsList, ppsList); 
    
         // Add packet to video track 
         outTrack.addFrame(new MP4Packet(result, frameNo, 25, 1, frameNo, true, null, frameNo, 0)); 
    
         frameNo++; 
        } 
    
        public void finish() throws IOException { 
         // Push saved SPS/PPS to a special storage in MP4 
         outTrack.addSampleEntry(H264Utils.createMOVSampleEntry(spsList, ppsList)); 
    
         // Write MP4 header and finalize recording 
         muxer.writeHeader(); 
         NIOUtils.closeQuietly(ch); 
        } 
    
        public static void main(String[] args) throws IOException { 
         SequenceEncoder encoder = new SequenceEncoder(new File("video.mp4")); 
         for (int i = 1; i < 100; i++) { 
          BufferedImage bi = ImageIO.read(new File(String.format("folder/img%08d.png", i))); 
          encoder.encodeImage(bi); 
         } 
         encoder.finish(); 
        } 
    } 
    
    +8

    Wir können leider nicht BufferedImage auf Android verwenden. Android hat keinen Zugriff auf java.awt. *. – BVB

    +0

    @Stanislav jede Lösung anstelle von BufferedImage für Android? – Ehsan

    +0

    @ user2204093 Dieses Code-Snippet ist veraltet. JCodec hat jetzt einen Android-Port –

    Verwandte Themen