MediaMuxer video-Datei-Größe zu reduzieren (re-komprimieren, verringern Sie die Auflösung)

Ich bin auf der Suche nach effizienten Weg zur Verringerung der einige video-Gewicht (als File, für den upload) und die offensichtliche Antwort ist: ermöglicht das reduzieren der Auflösung! (fullHD-oder 4K nicht notwendig, einfaches HD reicht mir) ich habe versucht, viele Möglichkeiten, die arbeiten sollten durch eine Menge von APIs (benötigt 10) und der beste Weg war, mit android-ffmpeg-java, ABER... auf meine ziemlich schnell fast-aktuelle Flaggschiff-Gerät ganze Prozess dauert etwa length_of_video*4 Sekunden und auch diese lib Gewicht ist 9 Mb, dieser Betrag erhöht sich meine app Größe... No wai! (12 Mb auf 1 Mb ist schönes Ergebnis, aber immer noch zu viele Fehler)

So, ich habe beschlossen, den Einsatz von nativen Android Möglichkeiten, dies zu tun, MediaMuxer und MediaCodec - Sie sind von API18 und API16 erstellt (ältere Geräte-Nutzer: tut mir Leid; aber oft haben Sie auch "lower-res" - Kamera). Unter Methode fast funktioniert - MediaMuxer NICHT respektieren MediaFormat.KEY_WIDTH und MediaFormat.KEY_HEIGHT - extrahiert File ist "re-komprimiert", das Gewicht ist ein bisschen kleiner, aber die Auflösung ist die gleiche wie im original-video File...

So, Frage: Wie komprimieren und re-Skalierung/ändern der Auflösung von video mit MediaMuxer und anderen zugehörigen Klassen und Methoden?

public File getCompressedFile(String videoPath) throws IOException{
    MediaExtractor extractor = new MediaExtractor();
    extractor.setDataSource(videoPath);
    int trackCount = extractor.getTrackCount();

    String filePath = videoPath.substring(0, videoPath.lastIndexOf(File.separator));
    String[] splitByDot = videoPath.split("\\.");
    String ext="";
    if(splitByDot!=null && splitByDot.length>1)
        ext = splitByDot[splitByDot.length-1];
    String fileName = videoPath.substring(videoPath.lastIndexOf(File.separator)+1,
                    videoPath.length());
    if(ext.length()>0)
        fileName=fileName.replace("."+ext, "_out."+ext);
    else
        fileName=fileName.concat("_out");

    final File outFile = new File(filePath, fileName);
    if(!outFile.exists())
        outFile.createNewFile();

    MediaMuxer muxer = new MediaMuxer(outFile.getAbsolutePath(),
            MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);
    HashMap<Integer, Integer> indexMap = new HashMap<Integer, Integer>(trackCount);
    for (int i = 0; i < trackCount; i++) {
        extractor.selectTrack(i);
        MediaFormat format = extractor.getTrackFormat(i);
        String mime = format.getString(MediaFormat.KEY_MIME);
        if(mime!=null && mime.startsWith("video")){
            int currWidth = format.getInteger(MediaFormat.KEY_WIDTH);
            int currHeight = format.getInteger(MediaFormat.KEY_HEIGHT);
            format.setInteger(MediaFormat.KEY_WIDTH, currWidth>currHeight ? 960 : 540);
            format.setInteger(MediaFormat.KEY_HEIGHT, currWidth>currHeight ? 540 : 960);
            //API19 MediaFormat.KEY_MAX_WIDTH and KEY_MAX_HEIGHT
            format.setInteger("max-width", format.getInteger(MediaFormat.KEY_WIDTH));
            format.setInteger("max-height", format.getInteger(MediaFormat.KEY_HEIGHT));
        }
        int dstIndex = muxer.addTrack(format);
        indexMap.put(i, dstIndex);
    }

    boolean sawEOS = false;
    int bufferSize = 256 * 1024;
    int offset = 100;
    ByteBuffer dstBuf = ByteBuffer.allocate(bufferSize);
    MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();
    muxer.start();
    while (!sawEOS) {
        bufferInfo.offset = offset;
        bufferInfo.size = extractor.readSampleData(dstBuf, offset);
        if (bufferInfo.size < 0) {
            sawEOS = true;
            bufferInfo.size = 0;
        } else {
            bufferInfo.presentationTimeUs = extractor.getSampleTime();
            bufferInfo.flags = extractor.getSampleFlags();
            int trackIndex = extractor.getSampleTrackIndex();
            muxer.writeSampleData(indexMap.get(trackIndex), dstBuf,
                    bufferInfo);
            extractor.advance();
        }
    }

    muxer.stop();
    muxer.release();

    return outFile;
}

PS. viele nützliche Sachen über muxer hier, obigen code Basen auf MediaMuxerTest.java Methode cloneMediaUsingMuxer

InformationsquelleAutor snachmsm | 2015-04-29
Schreibe einen Kommentar