├── .gitignore ├── README.md ├── app ├── build.gradle └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── codepath │ │ └── examples │ │ └── audiovideodemo │ │ ├── AudioActivity.java │ │ ├── MainActivity.java │ │ └── VideoActivity.java │ └── res │ ├── drawable-hdpi │ └── ic_launcher.png │ ├── drawable-mdpi │ └── ic_launcher.png │ ├── drawable-xhdpi │ └── ic_launcher.png │ ├── drawable-xxhdpi │ └── ic_launcher.png │ ├── layout │ ├── activity_audio.xml │ ├── activity_main.xml │ └── activity_video.xml │ ├── menu │ ├── audio.xml │ ├── main.xml │ └── video.xml │ ├── raw │ ├── sample_audio.mp3 │ └── small_video.mp4 │ ├── values-v11 │ └── styles.xml │ ├── values-v14 │ └── styles.xml │ ├── values-w820dp │ └── dimens.xml │ └── values │ ├── dimens.xml │ ├── strings.xml │ └── styles.xml ├── build.gradle ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | # Source: https://gist.github.com/nesquena/5617544/raw/53710b374e7df3302df43b552488d876040ada3d/.gitignore 2 | 3 | # built application files 4 | *.apk 5 | *.ap_ 6 | 7 | # files for the dex VM 8 | *.dex 9 | 10 | # Java class files 11 | *.class 12 | 13 | # generated files 14 | bin/ 15 | gen/ 16 | 17 | # Local configuration file (sdk path, etc) 18 | local.properties 19 | 20 | # Eclipse project files 21 | .classpath 22 | .project 23 | 24 | # Proguard folder generated by Eclipse 25 | proguard/ 26 | proguard-project.txt 27 | 28 | # Intellij project files 29 | *.iml 30 | *.ipr 31 | *.iws 32 | .idea/ 33 | 34 | *.pydevproject 35 | .project 36 | .metadata 37 | bin/** 38 | tmp/** 39 | tmp/**/* 40 | *.tmp 41 | *.bak 42 | *.swp 43 | *~.nib 44 | local.properties 45 | .classpath 46 | .settings/ 47 | .loadpath 48 | 49 | # External tool builders 50 | .externalToolBuilders/ 51 | 52 | # Locally stored "Eclipse launch configurations" 53 | *.launch 54 | 55 | # CDT-specific 56 | .cproject 57 | 58 | # PDT-specific 59 | .buildpath 60 | 61 | # Android Studio project files 62 | *.iml 63 | .gradle 64 | .idea 65 | build 66 | import-summary.txt 67 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Audio and Video Demo 2 | 3 | Demo which shows how to playback and capture audio / video within an Android application. Check out the corresponding [Audio / Video Cliffnotes](http://guides.thecodepath.com/android/Video-and-Audio-Playback-and-Recording) for a more detailed tutorial of how this works. 4 | 5 | Features: 6 | 7 | * Play a local audio file 8 | * Stream a remote audio file 9 | * Capture audio from mic and playback 10 | * Play a local video 11 | * Stream a remote video 12 | * Capture a video using camera and playback 13 | 14 | Screens: 15 | 16 |   17 |   18 | 19 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 21 5 | buildToolsVersion "22.0.1" 6 | 7 | defaultConfig { 8 | applicationId "com.codepath.examples.audiovideodemo" 9 | minSdkVersion 18 10 | targetSdkVersion 21 11 | } 12 | 13 | buildTypes { 14 | release { 15 | minifyEnabled false 16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt' 17 | } 18 | } 19 | } 20 | 21 | dependencies { 22 | compile 'com.android.support:appcompat-v7:22.2.0' 23 | compile 'com.android.support:support-v4:22.2.0' 24 | } 25 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 10 | 11 | 12 | 13 | 14 | 15 | 20 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 33 | 36 | 37 | 41 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /app/src/main/java/com/codepath/examples/audiovideodemo/AudioActivity.java: -------------------------------------------------------------------------------- 1 | package com.codepath.examples.audiovideodemo; 2 | 3 | import java.io.IOException; 4 | 5 | import android.content.pm.PackageManager; 6 | import android.media.AudioManager; 7 | import android.media.MediaPlayer; 8 | import android.media.MediaPlayer.OnErrorListener; 9 | import android.media.MediaPlayer.OnPreparedListener; 10 | import android.media.MediaRecorder; 11 | import android.os.Bundle; 12 | import android.os.Environment; 13 | import android.support.v7.app.AppCompatActivity; 14 | import android.view.Menu; 15 | import android.view.MenuItem; 16 | import android.view.View; 17 | import android.widget.Button; 18 | import android.widget.Toast; 19 | 20 | public class AudioActivity extends AppCompatActivity { 21 | 22 | @Override 23 | protected void onCreate(Bundle savedInstanceState) { 24 | super.onCreate(savedInstanceState); 25 | setContentView(R.layout.activity_audio); 26 | } 27 | 28 | public void onPlayLocalAudio(View v) { 29 | MediaPlayer mediaPlayer = MediaPlayer.create(this, R.raw.sample_audio); 30 | mediaPlayer.start(); 31 | } 32 | 33 | public void onStreamAudio(View v) { 34 | String url = "https://dl.dropboxusercontent.com/u/10281242/sample_audio.mp3"; // your URL here 35 | final MediaPlayer mediaPlayer = new MediaPlayer(); 36 | mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); 37 | // Listen for if the audio file can't be prepared 38 | mediaPlayer.setOnErrorListener(new OnErrorListener() { 39 | @Override 40 | public boolean onError(MediaPlayer mp, int what, int extra) { 41 | // ... react appropriately ... 42 | // The MediaPlayer has moved to the Error state, must be reset! 43 | return false; 44 | } 45 | }); 46 | // Attach to when audio file is prepared for playing 47 | mediaPlayer.setOnPreparedListener(new OnPreparedListener() { 48 | @Override 49 | public void onPrepared(MediaPlayer mp) { 50 | mediaPlayer.start(); 51 | } 52 | }); 53 | // Set the data source to the remote URL 54 | // Trigger an async preparation which will file listener when completed 55 | try { 56 | mediaPlayer.setDataSource(url); 57 | mediaPlayer.prepareAsync(); // might take long! (for buffering, etc) 58 | } catch (IllegalArgumentException e) { 59 | e.printStackTrace(); 60 | } catch (SecurityException e) { 61 | e.printStackTrace(); 62 | } catch (IllegalStateException e) { 63 | e.printStackTrace(); 64 | } catch (IOException e) { 65 | e.printStackTrace(); 66 | } 67 | } 68 | 69 | MediaRecorder mediaRecorder; 70 | String mFileName; 71 | public void onRecordAudio(View v) { 72 | // Verify that the device has a mic 73 | PackageManager pmanager = this.getPackageManager(); 74 | if (!pmanager.hasSystemFeature(PackageManager.FEATURE_MICROPHONE)) { 75 | Toast.makeText(this, "This device doesn't have a mic!", Toast.LENGTH_LONG).show(); 76 | return; 77 | } 78 | 79 | 80 | Button btnRecord = (Button) v; 81 | // Start the recording 82 | if (v.getTag() == "start" || v.getTag() == null) { 83 | mFileName = Environment.getExternalStorageDirectory().getAbsolutePath(); 84 | mFileName += "/audiorecordtest.3gp"; 85 | mediaRecorder = new MediaRecorder(); 86 | 87 | mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); 88 | mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); 89 | mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); 90 | mediaRecorder.setOutputFile(mFileName); 91 | v.setTag("stop"); 92 | btnRecord.setText("Stop"); 93 | 94 | 95 | try { 96 | mediaRecorder.prepare(); 97 | mediaRecorder.start(); 98 | } catch (IllegalStateException e) { 99 | e.printStackTrace(); 100 | } catch (IOException e) { 101 | e.printStackTrace(); 102 | } 103 | } else if (v.getTag() == "stop") { 104 | mediaRecorder.stop(); 105 | mediaRecorder.reset(); 106 | mediaRecorder.release(); 107 | v.setTag("start"); 108 | btnRecord.setText("Record Audio"); 109 | MediaPlayer mediaPlayer = new MediaPlayer(); 110 | mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); 111 | try { 112 | mediaPlayer.setDataSource(mFileName); 113 | mediaPlayer.prepare(); // must call prepare first 114 | } catch (IllegalArgumentException e) { 115 | e.printStackTrace(); 116 | } catch (SecurityException e) { 117 | e.printStackTrace(); 118 | } catch (IllegalStateException e) { 119 | e.printStackTrace(); 120 | } catch (IOException e) { 121 | e.printStackTrace(); 122 | } 123 | mediaPlayer.start(); // then start 124 | } 125 | } 126 | 127 | @Override 128 | public boolean onCreateOptionsMenu(Menu menu) { 129 | 130 | // Inflate the menu; this adds items to the action bar if it is present. 131 | getMenuInflater().inflate(R.menu.audio, menu); 132 | return true; 133 | } 134 | 135 | @Override 136 | public boolean onOptionsItemSelected(MenuItem item) { 137 | // Handle action bar item clicks here. The action bar will 138 | // automatically handle clicks on the Home/Up button, so long 139 | // as you specify a parent activity in AndroidManifest.xml. 140 | int id = item.getItemId(); 141 | if (id == R.id.action_settings) { 142 | return true; 143 | } 144 | return super.onOptionsItemSelected(item); 145 | } 146 | 147 | 148 | } 149 | -------------------------------------------------------------------------------- /app/src/main/java/com/codepath/examples/audiovideodemo/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.codepath.examples.audiovideodemo; 2 | 3 | import android.content.Intent; 4 | import android.os.Bundle; 5 | import android.support.v7.app.AppCompatActivity; 6 | import android.view.Menu; 7 | import android.view.MenuItem; 8 | import android.view.View; 9 | 10 | public class MainActivity extends AppCompatActivity { 11 | 12 | @Override 13 | protected void onCreate(Bundle savedInstanceState) { 14 | super.onCreate(savedInstanceState); 15 | setContentView(R.layout.activity_main); 16 | } 17 | 18 | 19 | public void onAudio(View v) { 20 | startActivity(new Intent(this, AudioActivity.class)); 21 | } 22 | 23 | public void onVideo(View v) { 24 | startActivity(new Intent(this, VideoActivity.class)); 25 | } 26 | 27 | @Override 28 | public boolean onCreateOptionsMenu(Menu menu) { 29 | 30 | // Inflate the menu; this adds items to the action bar if it is present. 31 | getMenuInflater().inflate(R.menu.main, menu); 32 | return true; 33 | } 34 | 35 | @Override 36 | public boolean onOptionsItemSelected(MenuItem item) { 37 | // Handle action bar item clicks here. The action bar will 38 | // automatically handle clicks on the Home/Up button, so long 39 | // as you specify a parent activity in AndroidManifest.xml. 40 | int id = item.getItemId(); 41 | if (id == R.id.action_settings) { 42 | return true; 43 | } 44 | return super.onOptionsItemSelected(item); 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /app/src/main/java/com/codepath/examples/audiovideodemo/VideoActivity.java: -------------------------------------------------------------------------------- 1 | package com.codepath.examples.audiovideodemo; 2 | 3 | import java.io.File; 4 | 5 | import android.content.Intent; 6 | import android.content.pm.PackageManager; 7 | import android.media.MediaPlayer; 8 | import android.media.MediaPlayer.OnPreparedListener; 9 | import android.net.Uri; 10 | import android.os.Bundle; 11 | import android.os.Environment; 12 | import android.provider.MediaStore; 13 | import android.support.v7.app.AppCompatActivity; 14 | import android.view.Menu; 15 | import android.view.MenuItem; 16 | import android.view.View; 17 | import android.widget.MediaController; 18 | import android.widget.Toast; 19 | import android.widget.VideoView; 20 | 21 | public class VideoActivity extends AppCompatActivity { 22 | 23 | @Override 24 | protected void onCreate(Bundle savedInstanceState) { 25 | super.onCreate(savedInstanceState); 26 | setContentView(R.layout.activity_video); 27 | } 28 | 29 | public void onPlayLocalVideo(View v) { 30 | VideoView mVideoView = (VideoView) findViewById(R.id.video_view); 31 | mVideoView.setVideoURI(Uri.parse("android.resource://" + getPackageName() + "/" 32 | + R.raw.small_video)); 33 | mVideoView.setMediaController(new MediaController(this)); 34 | mVideoView.requestFocus(); 35 | mVideoView.start(); 36 | } 37 | 38 | public void onStreamVideo(View v) { 39 | final VideoView mVideoView = (VideoView) findViewById(R.id.video_view); 40 | mVideoView.setVideoPath("http://techslides.com/demos/sample-videos/small.mp4"); 41 | MediaController mediaController = new MediaController(this); 42 | mediaController.setAnchorView(mVideoView); 43 | mVideoView.setMediaController(mediaController); 44 | mVideoView.requestFocus(); 45 | mVideoView.setOnPreparedListener(new OnPreparedListener() { 46 | // Close the progress bar and play the video 47 | public void onPrepared(MediaPlayer mp) { 48 | mVideoView.start(); 49 | } 50 | }); 51 | } 52 | 53 | private static final int VIDEO_CAPTURE = 101; 54 | Uri videoUri; 55 | public void onRecordVideo(View v) { 56 | if (getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FRONT)) { 57 | Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE); 58 | File mediaFile = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/myvideo.mp4"); 59 | videoUri = Uri.fromFile(mediaFile); 60 | intent.putExtra(MediaStore.EXTRA_OUTPUT, videoUri); 61 | startActivityForResult(intent, VIDEO_CAPTURE); 62 | } else { 63 | Toast.makeText(this, "No camera on device", Toast.LENGTH_LONG).show(); 64 | } 65 | } 66 | 67 | protected void onActivityResult(int requestCode, int resultCode, Intent data) { 68 | if (requestCode == VIDEO_CAPTURE) { 69 | if (resultCode == RESULT_OK) { 70 | VideoView mVideoView = (VideoView) findViewById(R.id.video_view); 71 | mVideoView.setVideoURI(videoUri); 72 | mVideoView.setMediaController(new MediaController(this)); 73 | mVideoView.requestFocus(); 74 | mVideoView.start(); 75 | } else if (resultCode == RESULT_CANCELED) { 76 | Toast.makeText(this, "Video recording cancelled.", Toast.LENGTH_LONG).show(); 77 | } else { 78 | Toast.makeText(this, "Failed to record video", Toast.LENGTH_LONG).show(); 79 | } 80 | } 81 | } 82 | 83 | @Override 84 | public boolean onCreateOptionsMenu(Menu menu) { 85 | 86 | // Inflate the menu; this adds items to the action bar if it is present. 87 | getMenuInflater().inflate(R.menu.video, menu); 88 | return true; 89 | } 90 | 91 | @Override 92 | public boolean onOptionsItemSelected(MenuItem item) { 93 | // Handle action bar item clicks here. The action bar will 94 | // automatically handle clicks on the Home/Up button, so long 95 | // as you specify a parent activity in AndroidManifest.xml. 96 | int id = item.getItemId(); 97 | if (id == R.id.action_settings) { 98 | return true; 99 | } 100 | return super.onOptionsItemSelected(item); 101 | } 102 | 103 | } 104 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codepath/android-audio-video-demo/b365dc8ba4d606d43f20464a03a3ed30c4e232a5/app/src/main/res/drawable-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codepath/android-audio-video-demo/b365dc8ba4d606d43f20464a03a3ed30c4e232a5/app/src/main/res/drawable-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codepath/android-audio-video-demo/b365dc8ba4d606d43f20464a03a3ed30c4e232a5/app/src/main/res/drawable-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/codepath/android-audio-video-demo/b365dc8ba4d606d43f20464a03a3ed30c4e232a5/app/src/main/res/drawable-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_audio.xml: -------------------------------------------------------------------------------- 1 | 10 | 11 | 18 | 19 |