package com.example.videoextraction; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.nio.ByteBuffer; import java.util.Date; import android.annotation.SuppressLint; import android.app.Activity; import android.content.Intent; import android.database.Cursor; import android.media.MediaCodec; import android.media.MediaCodecInfo; import android.media.MediaFormat; import android.media.MediaMuxer; import android.net.Uri; import android.os.Bundle; import android.os.Environment; import android.provider.MediaStore; import android.util.Log; import android.view.Menu; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.TextView; import android.widget.Toast; @SuppressLint("UseSparseArrays") public class MainActivity extends Activity implements OnClickListener{ private static final int chooseVid=1; private static final String TAG="MainActivity"; //private static final boolean VERBOSE=false; //private static final int MAX_SAMPLE_SIZE = 256 * 1024; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //SET UP BUTTON CLICK LISTENERS ((Button)findViewById(R.id.chooseVid)).setOnClickListener(this); ((Button)findViewById(R.id.exitButton)).setOnClickListener(this); } public void onActivityResult(int requestCode,int resultCode,Intent data) { if(resultCode==RESULT_OK) { if(requestCode==chooseVid) { Uri uri=data.getData(); String path=getPath(uri); Toast.makeText(getApplicationContext(), path, Toast.LENGTH_LONG).show(); createNewFolder(); boolean res=false; try { res=testAudioOnly(path); } catch (Exception e) { e.printStackTrace(); } if(res) { TextView tv=(TextView)findViewById(R.id.textView1); tv.setVisibility(1); tv.setText("Success"); } else { TextView tv=(TextView)findViewById(R.id.textView1); tv.setVisibility(1); tv.setText("Failed"); } } } } private String getPath(Uri uri) { String[] projection={MediaStore.Video.Media.DATA}; Cursor cursor=null; String result="Error"; try { cursor=getContentResolver().query(uri,projection,null,null,null); int column_index=cursor.getColumnIndex(MediaStore.Video.Media.DATA); cursor.moveToFirst(); result=cursor.getString(column_index).toString(); } finally { if(cursor!=null) cursor.close(); } return result; } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.main, menu); return true; } private void createNewFolder() { String targetPath=Environment.getExternalStorageDirectory().toString()+"/VidEx"; File file = new File(targetPath); if (!file.exists()) { if (!file.mkdirs()) { Toast.makeText(getApplicationContext(), "Cannot access external storage.", Toast.LENGTH_LONG).show(); } else { TextView tv=(TextView)findViewById(R.id.textView1); tv.setVisibility(1); tv.setText(targetPath); } } else { TextView tv=(TextView)findViewById(R.id.textView1); tv.setVisibility(1); tv.setText(targetPath); } } @Override public void onClick(View v) { switch(v.getId()) { case R.id.chooseVid: Intent intent=new Intent(Intent.ACTION_PICK,android.provider.MediaStore.Video.Media.EXTERNAL_CONTENT_URI); startActivityForResult(intent,chooseVid); break; case R.id.exitButton: this.finish(); break; } } public boolean testAudioOnly(String source) throws Exception { String outputFile = "/storage/emulated/0/VidEx/audioOnly"+new Date().getTime()+".mp4"; boolean s=false; try { s=cloneMediaUsingMuxer(source, outputFile, 1, -1); } catch(Exception e) { e.printStackTrace(); } return s; } private boolean cloneMediaUsingMuxer(String filePath, String dstMediaPath,int expectedTrackCount, int degrees) throws IOException { final String COMPRESSED_AUDIO_FILE_MIME_TYPE = "audio/mp4a-latm"; final int COMPRESSED_AUDIO_FILE_BIT_RATE = 128000; // 128kbps final int SAMPLING_RATE = 44100; final int CODEC_TIMEOUT_IN_MS = 5000; final int BUFFER_SIZE = 88200; boolean suc=false; try { File inputFile = new File(filePath); FileInputStream fis = new FileInputStream(inputFile); File outputFile = new File(dstMediaPath); if (outputFile.exists()) outputFile.delete(); MediaMuxer mux = new MediaMuxer(outputFile.getAbsolutePath(), MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4); MediaFormat outputFormat = MediaFormat.createAudioFormat(COMPRESSED_AUDIO_FILE_MIME_TYPE,SAMPLING_RATE, 1); outputFormat.setInteger(MediaFormat.KEY_AAC_PROFILE, MediaCodecInfo.CodecProfileLevel.AACObjectLC); outputFormat.setInteger(MediaFormat.KEY_BIT_RATE, COMPRESSED_AUDIO_FILE_BIT_RATE); MediaCodec codec = MediaCodec.createEncoderByType(COMPRESSED_AUDIO_FILE_MIME_TYPE); codec.configure(outputFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE); codec.start(); ByteBuffer[] codecInputBuffers = codec.getInputBuffers(); // Note: Array of buffers ByteBuffer[] codecOutputBuffers = codec.getOutputBuffers(); MediaCodec.BufferInfo outBuffInfo = new MediaCodec.BufferInfo(); byte[] tempBuffer = new byte[BUFFER_SIZE]; boolean hasMoreData = true; double presentationTimeUs = 0; int audioTrackIdx = 0; int totalBytesRead = 0; int percentComplete; do { int inputBufIndex = 0; while (inputBufIndex != -1 && hasMoreData) { inputBufIndex = codec.dequeueInputBuffer(CODEC_TIMEOUT_IN_MS); if (inputBufIndex >= 0) { ByteBuffer dstBuf = codecInputBuffers[inputBufIndex]; dstBuf.clear(); int bytesRead = fis.read(tempBuffer, 0, dstBuf.limit()); if (bytesRead == -1) { // -1 implies EOS hasMoreData = false; codec.queueInputBuffer(inputBufIndex, 0, 0, (long) presentationTimeUs, MediaCodec.BUFFER_FLAG_END_OF_STREAM); } else { totalBytesRead += bytesRead; dstBuf.put(tempBuffer, 0, bytesRead); codec.queueInputBuffer(inputBufIndex, 0, bytesRead, (long) presentationTimeUs, 0); presentationTimeUs = 1000000l * (totalBytesRead / 2) / SAMPLING_RATE; } } } // Drain audio int outputBufIndex = 0; while (outputBufIndex != MediaCodec.INFO_TRY_AGAIN_LATER) { outputBufIndex = codec.dequeueOutputBuffer(outBuffInfo, CODEC_TIMEOUT_IN_MS); if (outputBufIndex >= 0) { ByteBuffer encodedData = codecOutputBuffers[outputBufIndex]; encodedData.position(outBuffInfo.offset); encodedData.limit(outBuffInfo.offset + outBuffInfo.size); if ((outBuffInfo.flags & MediaCodec.BUFFER_FLAG_CODEC_CONFIG) != 0 && outBuffInfo.size != 0) { codec.releaseOutputBuffer(outputBufIndex, false); outBuffInfo.size=0; } else { mux.writeSampleData(audioTrackIdx, codecOutputBuffers[outputBufIndex], outBuffInfo); codec.releaseOutputBuffer(outputBufIndex, false); } } else if (outputBufIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) { outputFormat = codec.getOutputFormat(); Log.v(TAG, "Output format changed - " + outputFormat); audioTrackIdx = mux.addTrack(outputFormat); mux.start(); } else if (outputBufIndex == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) { Log.e(TAG, "Output buffers changed during encode!"); } else if (outputBufIndex == MediaCodec.INFO_TRY_AGAIN_LATER) { // NO OP } else { Log.e(TAG, "Unknown return code from dequeueOutputBuffer - " + outputBufIndex); } } percentComplete = (int) Math.round(((float) totalBytesRead / (float) inputFile.length()) * 100.0); Log.v(TAG, "Conversion % - "+ percentComplete); } while (outBuffInfo.flags != MediaCodec.BUFFER_FLAG_END_OF_STREAM); fis.close(); mux.stop(); mux.release(); Log.v(TAG, "Compression done ..."); suc=true; } catch (FileNotFoundException e) { Log.e(TAG, "File not found!", e); suc=false; } catch (IOException e) { Log.e(TAG, "IO exception!", e); suc=false; } return suc; } /* // Set up MediaExtractor to read from the source. //AssetFileDescriptor srcFd = mResources.openRawResourceFd(srcMedia); MediaExtractor extractor = new MediaExtractor(); extractor.setDataSource(srcMedia); int trackCount = extractor.getTrackCount(); // Set up MediaMuxer for the destination. MediaMuxer muxer=null; muxer = new MediaMuxer(dstMediaPath, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4); muxer.addTrack(MediaFormat.createAudioFormat("audio/mp4a-latm", 48000, 1)); // Set up the tracks. HashMap<Integer, Integer> indexMap = new HashMap<Integer, Integer>(trackCount); for (int i = 0; i < trackCount; i++) { extractor.selectTrack(i); MediaFormat format = extractor.getTrackFormat(i); int dstIndex = muxer.addTrack(format); indexMap.put(i, dstIndex); } // Copy the samples from MediaExtractor to MediaMuxer. boolean sawEOS = false; int bufferSize = MAX_SAMPLE_SIZE; int frameCount = 0; int offset = 100; ByteBuffer dstBuf = ByteBuffer.allocate(bufferSize); BufferInfo bufferInfo = new BufferInfo(); if (degrees >= 0) { muxer.setOrientationHint(degrees); } muxer.start(); while (!sawEOS) { bufferInfo.offset = offset; bufferInfo.size = extractor.readSampleData(dstBuf, offset); if (bufferInfo.size < 0) { if (VERBOSE) { Log.d(TAG, "saw input EOS."); } 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(); frameCount++; if (VERBOSE) { Log.d(TAG, "Frame (" + frameCount + ") " + "PresentationTimeUs:" + bufferInfo.presentationTimeUs + " Flags:" + bufferInfo.flags + " TrackIndex:" + trackIndex + " Size(KB) " + bufferInfo.size / 1024); } } } muxer.stop(); muxer.release(); suc=true; return suc; } */ }