android - MediaMuxer video file size reducing (re-compress, decrease resolution) -


i'm looking efficient way reduce video weight (as file, upload) , obvious answer is: lets reduce resolution! (fullhd or 4k not needed, simple hd sufficient me) i've tried lot of ways should work through lot of apis (needed 10) , best way using android-ffmpeg-java, but... on pretty fast almost-current flagship device whole process lasts length_of_video*4 seconds , lib weight 9 mb, amount increases app size... no wai! (12 mb 1 mb nice result, still many flaws)

so i've decided use native android ways this, mediamuxer , mediacodec - available api18 , api16 respectivelly (older devices users: sorry; have "lower-res" camera). below method almost works - mediamuxer not respect mediaformat.key_width , mediaformat.key_height - extracted file "re-compressed", weight bit smaller, resolution same in original video file...

so, question: how compress , re-scale/change resolution of video using mediamuxer , other accompanying classes , methods?

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);     (int = 0; < 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 , 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. lot of usefull stuff muxer here, above code bases on mediamuxertest.java, method clonemediausingmuxer

basing on bigflake.com/mediacodec/ (awesome source of knowledge media-classes) i've tried few ways , extractdecodeeditencodemuxtest turned out helpfull. test wasn't described in article on bigflake site, can found here next other classes mentioned in text.

so, i've copied of code above mentioned extractdecodeeditencodemuxtest class, rewrote methods , there is: videoresolutionchanger. of course besides changing resolution re-encode output media. gives me 2mb hd video 16 mb fullhd. nice! , fast! whole process bit longer input video file duration on 4x2,5 ghz, 3 gb ram, adreno 330 device - e.g. 10 sec video input -> 11-12 secs of processing. mentioned in question ffmpeg-java smth 40 secs or more (and 9 mb more app). tests i've used mp4 videos recorded phone.

here go:

videoresolutionchanger:

@targetapi(18) public class videoresolutionchanger {      private static final int timeout_usec = 10000;      private static final string output_video_mime_type = "video/avc";     private static final int output_video_bit_rate = 2048 * 1024;     private static final int output_video_frame_rate = 30;     private static final int output_video_iframe_interval = 10;     private static final int output_video_color_format =             mediacodecinfo.codeccapabilities.color_formatsurface;      private static final string output_audio_mime_type = "audio/mp4a-latm";     private static final int output_audio_channel_count = 2;     private static final int output_audio_bit_rate = 128 * 1024;     private static final int output_audio_aac_profile =             mediacodecinfo.codecprofilelevel.aacobjecthe;     private static final int output_audio_sample_rate_hz = 44100;      private int mwidth = 1280;     private int mheight = 720;     private string moutputfile, minputfile;      public string changeresolution(file f)             throws throwable {         minputfile=f.getabsolutepath();          string filepath = minputfile.substring(0, minputfile.lastindexof(file.separator));         string[] splitbydot = minputfile.split("\\.");         string ext="";         if(splitbydot!=null && splitbydot.length>1)             ext = splitbydot[splitbydot.length-1];         string filename = minputfile.substring(minputfile.lastindexof(file.separator)+1,                 minputfile.length());         if(ext.length()>0)             filename=filename.replace("."+ext, "_out.mp4");         else             filename=filename.concat("_out.mp4");          final file outfile = new file(environment.getexternalstoragedirectory(), filename);         if(!outfile.exists())             outfile.createnewfile();          moutputfile=outfile.getabsolutepath();          changerwrapper.changeresolutioninseparatedthread(this);          return moutputfile;     }      private static class changerwrapper implements runnable {          private throwable mthrowable;         private videoresolutionchanger mchanger;          private changerwrapper(videoresolutionchanger changer) {             mchanger = changer;         }          @override         public void run() {             try {                 mchanger.prepareandchangeresolution();             } catch (throwable th) {                 mthrowable = th;             }         }          public static void changeresolutioninseparatedthread(videoresolutionchanger changer)                 throws throwable {             changerwrapper wrapper = new changerwrapper(changer);             thread th = new thread(wrapper, changerwrapper.class.getsimplename());             th.start();             th.join();             if (wrapper.mthrowable != null)                 throw wrapper.mthrowable;         }     }      private void prepareandchangeresolution() throws exception {         exception exception = null;          mediacodecinfo videocodecinfo = selectcodec(output_video_mime_type);         if (videocodecinfo == null)             return;         mediacodecinfo audiocodecinfo = selectcodec(output_audio_mime_type);         if (audiocodecinfo == null)             return;          mediaextractor videoextractor = null;         mediaextractor audioextractor = null;         outputsurface outputsurface = null;         mediacodec videodecoder = null;         mediacodec audiodecoder = null;         mediacodec videoencoder = null;         mediacodec audioencoder = null;         mediamuxer muxer = null;         inputsurface inputsurface = null;         try {             videoextractor = createextractor();             int videoinputtrack = getandselectvideotrackindex(videoextractor);             mediaformat inputformat = videoextractor.gettrackformat(videoinputtrack);              mediametadataretriever m = new mediametadataretriever();             m.setdatasource(minputfile);             bitmap thumbnail = m.getframeattime();             int inputwidth = thumbnail.getwidth(),                 inputheight = thumbnail.getheight();              if(inputwidth>inputheight){                 if(mwidth<mheight){                     int w = mwidth;                     mwidth=mheight;                     mheight=w;                 }             }             else{                 if(mwidth>mheight){                     int w = mwidth;                     mwidth=mheight;                     mheight=w;                 }             }              mediaformat outputvideoformat =                     mediaformat.createvideoformat(output_video_mime_type, mwidth, mheight);             outputvideoformat.setinteger(                     mediaformat.key_color_format, output_video_color_format);             outputvideoformat.setinteger(mediaformat.key_bit_rate, output_video_bit_rate);             outputvideoformat.setinteger(mediaformat.key_frame_rate, output_video_frame_rate);             outputvideoformat.setinteger(                     mediaformat.key_i_frame_interval, output_video_iframe_interval);              atomicreference<surface> inputsurfacereference = new atomicreference<surface>();             videoencoder = createvideoencoder(                     videocodecinfo, outputvideoformat, inputsurfacereference);             inputsurface = new inputsurface(inputsurfacereference.get());             inputsurface.makecurrent();              outputsurface = new outputsurface();             videodecoder = createvideodecoder(inputformat, outputsurface.getsurface());              audioextractor = createextractor();             int audioinputtrack = getandselectaudiotrackindex(audioextractor);             mediaformat inputaudioformat = audioextractor.gettrackformat(audioinputtrack);             mediaformat outputaudioformat =                 mediaformat.createaudioformat(inputaudioformat.getstring(mediaformat.key_mime),                         inputaudioformat.getinteger(mediaformat.key_sample_rate),                         inputaudioformat.getinteger(mediaformat.key_channel_count));             outputaudioformat.setinteger(mediaformat.key_bit_rate, output_audio_bit_rate);             outputaudioformat.setinteger(mediaformat.key_aac_profile, output_audio_aac_profile);              audioencoder = createaudioencoder(audiocodecinfo, outputaudioformat);             audiodecoder = createaudiodecoder(inputaudioformat);              muxer = new mediamuxer(moutputfile, mediamuxer.outputformat.muxer_output_mpeg_4);              changeresolution(videoextractor, audioextractor,                     videodecoder, videoencoder,                     audiodecoder, audioencoder,                     muxer, inputsurface, outputsurface);         } {             try {                 if (videoextractor != null)                     videoextractor.release();             } catch(exception e) {                 if (exception == null)                     exception = e;             }             try {                 if (audioextractor != null)                     audioextractor.release();             } catch(exception e) {                 if (exception == null)                     exception = e;             }             try {                 if (videodecoder != null) {                     videodecoder.stop();                     videodecoder.release();                 }             } catch(exception e) {                 if (exception == null)                     exception = e;             }             try {                 if (outputsurface != null) {                     outputsurface.release();                 }             } catch(exception e) {                 if (exception == null)                     exception = e;             }             try {                 if (videoencoder != null) {                     videoencoder.stop();                     videoencoder.release();                 }             } catch(exception e) {                 if (exception == null)                     exception = e;             }             try {                 if (audiodecoder != null) {                     audiodecoder.stop();                     audiodecoder.release();                 }             } catch(exception e) {                 if (exception == null)                     exception = e;             }             try {                 if (audioencoder != null) {                     audioencoder.stop();                     audioencoder.release();                 }             } catch(exception e) {                 if (exception == null)                     exception = e;             }             try {                 if (muxer != null) {                     muxer.stop();                     muxer.release();                 }             } catch(exception e) {                 if (exception == null)                     exception = e;             }             try {                 if (inputsurface != null)                     inputsurface.release();             } catch(exception e) {                 if (exception == null)                     exception = e;             }         }         if (exception != null)             throw exception;     }      private mediaextractor createextractor() throws ioexception {         mediaextractor extractor;         extractor = new mediaextractor();         extractor.setdatasource(minputfile);         return extractor;     }      private mediacodec createvideodecoder(mediaformat inputformat, surface surface) throws ioexception {         mediacodec decoder = mediacodec.createdecoderbytype(getmimetypefor(inputformat));         decoder.configure(inputformat, surface, null, 0);         decoder.start();         return decoder;     }      private mediacodec createvideoencoder(mediacodecinfo codecinfo, mediaformat format,             atomicreference<surface> surfacereference) throws ioexception {         mediacodec encoder = mediacodec.createbycodecname(codecinfo.getname());         encoder.configure(format, null, null, mediacodec.configure_flag_encode);         surfacereference.set(encoder.createinputsurface());         encoder.start();         return encoder;     }      private mediacodec createaudiodecoder(mediaformat inputformat) throws ioexception {         mediacodec decoder = mediacodec.createdecoderbytype(getmimetypefor(inputformat));         decoder.configure(inputformat, null, null, 0);         decoder.start();         return decoder;     }      private mediacodec createaudioencoder(mediacodecinfo codecinfo, mediaformat format) throws ioexception {         mediacodec encoder = mediacodec.createbycodecname(codecinfo.getname());         encoder.configure(format, null, null, mediacodec.configure_flag_encode);         encoder.start();         return encoder;     }      private int getandselectvideotrackindex(mediaextractor extractor) {         (int index = 0; index < extractor.gettrackcount(); ++index) {             if (isvideoformat(extractor.gettrackformat(index))) {                 extractor.selecttrack(index);                 return index;             }         }         return -1;     }     private int getandselectaudiotrackindex(mediaextractor extractor) {         (int index = 0; index < extractor.gettrackcount(); ++index) {             if (isaudioformat(extractor.gettrackformat(index))) {                 extractor.selecttrack(index);                 return index;             }         }         return -1;     }      private void changeresolution(mediaextractor videoextractor, mediaextractor audioextractor,             mediacodec videodecoder, mediacodec videoencoder,             mediacodec audiodecoder, mediacodec audioencoder,             mediamuxer muxer,             inputsurface inputsurface, outputsurface outputsurface) {         bytebuffer[] videodecoderinputbuffers = null;         bytebuffer[] videodecoderoutputbuffers = null;         bytebuffer[] videoencoderoutputbuffers = null;         mediacodec.bufferinfo videodecoderoutputbufferinfo = null;         mediacodec.bufferinfo videoencoderoutputbufferinfo = null;          videodecoderinputbuffers = videodecoder.getinputbuffers();         videodecoderoutputbuffers = videodecoder.getoutputbuffers();         videoencoderoutputbuffers = videoencoder.getoutputbuffers();         videodecoderoutputbufferinfo = new mediacodec.bufferinfo();         videoencoderoutputbufferinfo = new mediacodec.bufferinfo();          bytebuffer[] audiodecoderinputbuffers = null;         bytebuffer[] audiodecoderoutputbuffers = null;         bytebuffer[] audioencoderinputbuffers = null;         bytebuffer[] audioencoderoutputbuffers = null;         mediacodec.bufferinfo audiodecoderoutputbufferinfo = null;         mediacodec.bufferinfo audioencoderoutputbufferinfo = null;          audiodecoderinputbuffers = audiodecoder.getinputbuffers();         audiodecoderoutputbuffers =  audiodecoder.getoutputbuffers();         audioencoderinputbuffers = audioencoder.getinputbuffers();         audioencoderoutputbuffers = audioencoder.getoutputbuffers();         audiodecoderoutputbufferinfo = new mediacodec.bufferinfo();         audioencoderoutputbufferinfo = new mediacodec.bufferinfo();          mediaformat decoderoutputvideoformat = null;         mediaformat decoderoutputaudioformat = null;         mediaformat encoderoutputvideoformat = null;         mediaformat encoderoutputaudioformat = null;         int outputvideotrack = -1;         int outputaudiotrack = -1;          boolean videoextractordone = false;         boolean videodecoderdone = false;         boolean videoencoderdone = false;          boolean audioextractordone = false;         boolean audiodecoderdone = false;         boolean audioencoderdone = false;          int pendingaudiodecoderoutputbufferindex = -1;         boolean muxing = false;         while ((!videoencoderdone) || (!audioencoderdone)) {             while (!videoextractordone                     && (encoderoutputvideoformat == null || muxing)) {                 int decoderinputbufferindex = videodecoder.dequeueinputbuffer(timeout_usec);                 if (decoderinputbufferindex == mediacodec.info_try_again_later)                     break;                  bytebuffer decoderinputbuffer = videodecoderinputbuffers[decoderinputbufferindex];                 int size = videoextractor.readsampledata(decoderinputbuffer, 0);                 long presentationtime = videoextractor.getsampletime();                  if (size >= 0) {                     videodecoder.queueinputbuffer(                             decoderinputbufferindex,                             0,                             size,                             presentationtime,                             videoextractor.getsampleflags());                 }                 videoextractordone = !videoextractor.advance();                 if (videoextractordone)                     videodecoder.queueinputbuffer(decoderinputbufferindex,                             0, 0, 0,  mediacodec.buffer_flag_end_of_stream);                 break;             }              while (!audioextractordone                     && (encoderoutputaudioformat == null || muxing)) {                 int decoderinputbufferindex = audiodecoder.dequeueinputbuffer(timeout_usec);                 if (decoderinputbufferindex == mediacodec.info_try_again_later)                     break;                  bytebuffer decoderinputbuffer = audiodecoderinputbuffers[decoderinputbufferindex];                 int size = audioextractor.readsampledata(decoderinputbuffer, 0);                 long presentationtime = audioextractor.getsampletime();                  if (size >= 0)                     audiodecoder.queueinputbuffer(decoderinputbufferindex, 0, size,                             presentationtime, audioextractor.getsampleflags());                  audioextractordone = !audioextractor.advance();                 if (audioextractordone)                     audiodecoder.queueinputbuffer(decoderinputbufferindex, 0, 0,                             0, mediacodec.buffer_flag_end_of_stream);                  break;             }              while (!videodecoderdone                     && (encoderoutputvideoformat == null || muxing)) {                 int decoderoutputbufferindex =                         videodecoder.dequeueoutputbuffer(                                 videodecoderoutputbufferinfo, timeout_usec);                 if (decoderoutputbufferindex == mediacodec.info_try_again_later)                     break;                  if (decoderoutputbufferindex == mediacodec.info_output_buffers_changed) {                     videodecoderoutputbuffers = videodecoder.getoutputbuffers();                     break;                 }                 if (decoderoutputbufferindex == mediacodec.info_output_format_changed) {                     decoderoutputvideoformat = videodecoder.getoutputformat();                     break;                 }                  bytebuffer decoderoutputbuffer =                         videodecoderoutputbuffers[decoderoutputbufferindex];                 if ((videodecoderoutputbufferinfo.flags & mediacodec.buffer_flag_codec_config)                         != 0) {                     videodecoder.releaseoutputbuffer(decoderoutputbufferindex, false);                     break;                 }                  boolean render = videodecoderoutputbufferinfo.size != 0;                 videodecoder.releaseoutputbuffer(decoderoutputbufferindex, render);                 if (render) {                     outputsurface.awaitnewimage();                     outputsurface.drawimage();                     inputsurface.setpresentationtime(                             videodecoderoutputbufferinfo.presentationtimeus * 1000);                     inputsurface.swapbuffers();                 }                 if ((videodecoderoutputbufferinfo.flags                         & mediacodec.buffer_flag_end_of_stream) != 0) {                     videodecoderdone = true;                     videoencoder.signalendofinputstream();                 }                 break;             }              while (!audiodecoderdone && pendingaudiodecoderoutputbufferindex == -1                     && (encoderoutputaudioformat == null || muxing)) {                 int decoderoutputbufferindex =                         audiodecoder.dequeueoutputbuffer(                                 audiodecoderoutputbufferinfo, timeout_usec);                 if (decoderoutputbufferindex == mediacodec.info_try_again_later)                     break;                  if (decoderoutputbufferindex == mediacodec.info_output_buffers_changed) {                     audiodecoderoutputbuffers = audiodecoder.getoutputbuffers();                     break;                 }                 if (decoderoutputbufferindex == mediacodec.info_output_format_changed) {                     decoderoutputaudioformat = audiodecoder.getoutputformat();                     break;                 }                 bytebuffer decoderoutputbuffer =                         audiodecoderoutputbuffers[decoderoutputbufferindex];                 if ((audiodecoderoutputbufferinfo.flags & mediacodec.buffer_flag_codec_config)                         != 0) {                     audiodecoder.releaseoutputbuffer(decoderoutputbufferindex, false);                     break;                 }                 pendingaudiodecoderoutputbufferindex = decoderoutputbufferindex;                 break;             }              while (pendingaudiodecoderoutputbufferindex != -1) {                 int encoderinputbufferindex = audioencoder.dequeueinputbuffer(timeout_usec);                 bytebuffer encoderinputbuffer = audioencoderinputbuffers[encoderinputbufferindex];                 int size = audiodecoderoutputbufferinfo.size;                 long presentationtime = audiodecoderoutputbufferinfo.presentationtimeus;                  if (size >= 0) {                     bytebuffer decoderoutputbuffer =                             audiodecoderoutputbuffers[pendingaudiodecoderoutputbufferindex]                                     .duplicate();                     decoderoutputbuffer.position(audiodecoderoutputbufferinfo.offset);                     decoderoutputbuffer.limit(audiodecoderoutputbufferinfo.offset + size);                     encoderinputbuffer.position(0);                     encoderinputbuffer.put(decoderoutputbuffer);                     audioencoder.queueinputbuffer(                             encoderinputbufferindex,                             0,                             size,                             presentationtime,                             audiodecoderoutputbufferinfo.flags);                 }                 audiodecoder.releaseoutputbuffer(pendingaudiodecoderoutputbufferindex, false);                 pendingaudiodecoderoutputbufferindex = -1;                 if ((audiodecoderoutputbufferinfo.flags                         & mediacodec.buffer_flag_end_of_stream) != 0)                     audiodecoderdone = true;                  break;             }              while (!videoencoderdone                     && (encoderoutputvideoformat == null || muxing)) {                 int encoderoutputbufferindex = videoencoder.dequeueoutputbuffer(                         videoencoderoutputbufferinfo, timeout_usec);                 if (encoderoutputbufferindex == mediacodec.info_try_again_later)                     break;                 if (encoderoutputbufferindex == mediacodec.info_output_buffers_changed) {                     videoencoderoutputbuffers = videoencoder.getoutputbuffers();                     break;                 }                 if (encoderoutputbufferindex == mediacodec.info_output_format_changed) {                     encoderoutputvideoformat = videoencoder.getoutputformat();                     break;                 }                  bytebuffer encoderoutputbuffer =                         videoencoderoutputbuffers[encoderoutputbufferindex];                 if ((videoencoderoutputbufferinfo.flags & mediacodec.buffer_flag_codec_config)                         != 0) {                     videoencoder.releaseoutputbuffer(encoderoutputbufferindex, false);                     break;                 }                 if (videoencoderoutputbufferinfo.size != 0) {                     muxer.writesampledata(                             outputvideotrack, encoderoutputbuffer, videoencoderoutputbufferinfo);                 }                 if ((videoencoderoutputbufferinfo.flags & mediacodec.buffer_flag_end_of_stream)                         != 0) {                     videoencoderdone = true;                 }                 videoencoder.releaseoutputbuffer(encoderoutputbufferindex, false);                 break;             }              while (!audioencoderdone                     && (encoderoutputaudioformat == null || muxing)) {                 int encoderoutputbufferindex = audioencoder.dequeueoutputbuffer(                         audioencoderoutputbufferinfo, timeout_usec);                 if (encoderoutputbufferindex == mediacodec.info_try_again_later) {                     break;                 }                 if (encoderoutputbufferindex == mediacodec.info_output_buffers_changed) {                     audioencoderoutputbuffers = audioencoder.getoutputbuffers();                     break;                 }                 if (encoderoutputbufferindex == mediacodec.info_output_format_changed) {                     encoderoutputaudioformat = audioencoder.getoutputformat();                     break;                 }                  bytebuffer encoderoutputbuffer =                         audioencoderoutputbuffers[encoderoutputbufferindex];                 if ((audioencoderoutputbufferinfo.flags & mediacodec.buffer_flag_codec_config)                         != 0) {                     audioencoder.releaseoutputbuffer(encoderoutputbufferindex, false);                     break;                 }                 if (audioencoderoutputbufferinfo.size != 0)                     muxer.writesampledata(                             outputaudiotrack, encoderoutputbuffer, audioencoderoutputbufferinfo);                 if ((audioencoderoutputbufferinfo.flags & mediacodec.buffer_flag_end_of_stream)                         != 0)                     audioencoderdone = true;                  audioencoder.releaseoutputbuffer(encoderoutputbufferindex, false);                  break;             }             if (!muxing && (encoderoutputaudioformat != null)                     && (encoderoutputvideoformat != null)) {                 outputvideotrack = muxer.addtrack(encoderoutputvideoformat);                 outputaudiotrack = muxer.addtrack(encoderoutputaudioformat);                 muxer.start();                 muxing = true;             }         }     }      private static boolean isvideoformat(mediaformat format) {         return getmimetypefor(format).startswith("video/");     }     private static boolean isaudioformat(mediaformat format) {         return getmimetypefor(format).startswith("audio/");     }     private static string getmimetypefor(mediaformat format) {         return format.getstring(mediaformat.key_mime);     }      private static mediacodecinfo selectcodec(string mimetype) {         int numcodecs = mediacodeclist.getcodeccount();         (int = 0; < numcodecs; i++) {             mediacodecinfo codecinfo = mediacodeclist.getcodecinfoat(i);             if (!codecinfo.isencoder()) {                 continue;             }             string[] types = codecinfo.getsupportedtypes();             (int j = 0; j < types.length; j++) {                 if (types[j].equalsignorecase(mimetype)) {                     return codecinfo;                 }             }         }         return null;     } } 

it needs inputsurface, outputsurface , texturerender, placed next extractdecodeeditencodemuxtest (above here link). put these 3 in same package videoresolutionchanger , use this:

try{     string pathtoreencodedfile =         new videoresolutionchanger().changeresolution(videofilepath); }catch(throwable t){/* smth wrong :( */} 

where videofilepath might obtained file using file.getabsolutepath().

i know it's not cleanest , not most-effective/efficient way, i've been looking similar code last 2 days , found lot of topics, redirected me inde, ffmpeg or jcodec, other left without proper answer. i'm leaving here, use wisely!

limitations:

  • above use-it-like-this snippet can not started in thread looper, e.g. straight inside activity. best way create intentservice , pass input file path string in intents bundle. can run changeresolution stright inside onhandleintent;
  • api18 , above (mediamuxer introduced);
  • api18 needs of course write_external_storage, api19 , above has "built-in";

@fadden thank you work , support! :)


Comments

Popular posts from this blog

php - failed to open stream: HTTP request failed! HTTP/1.0 400 Bad Request -

java - How to filter a backspace keyboard input -

java - Show Soft Keyboard when EditText Appears -