
image.png
錄制音樂
<!-- 授予該程序錄制聲音的權(quán)限 -->
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<!-- 授予該程序向外部存儲(chǔ)器寫入數(shù)據(jù)的權(quán)限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
public class MainActivity extends AppCompatActivity {
// 定義界面上的兩個(gè)按鈕
private ImageButton recordBn;
private ImageButton stopBn;
// 系統(tǒng)的音頻文件
private File soundFile;
private MediaRecorder mRecorder;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 獲取程序界面中的兩個(gè)按鈕
recordBn = findViewById(R.id.record);
stopBn = findViewById(R.id.stop);
stopBn.setEnabled(false);
requestPermissions(new String[]{Manifest.permission.RECORD_AUDIO,
Manifest.permission.WRITE_EXTERNAL_STORAGE}, 0x123);
}
@Override
public void onRequestPermissionsResult(int requestCode,
@NonNull String[] permissions, @NonNull int[] grantResults) {
if (requestCode == 0x123 && grantResults.length == 2
&& grantResults[0] == PackageManager.PERMISSION_GRANTED
&& grantResults[1] == PackageManager.PERMISSION_GRANTED) {
View.OnClickListener listener = source ->
{
int sourceId = source.getId();
if (sourceId == R.id.record) {
// 創(chuàng)建保存錄音的音頻文件
soundFile = new File(String.format("%s/%s.amr", getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS).toString(), System.currentTimeMillis()));
mRecorder = new MediaRecorder();
// 設(shè)置錄音的聲音來源
mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
// 設(shè)置錄制的聲音的輸出格式(必須在設(shè)置聲音編碼格式之前設(shè)置)
mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
// 設(shè)置聲音編碼格式
mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
mRecorder.setOutputFile(soundFile.getAbsolutePath());
try {
mRecorder.prepare();
} catch (IOException e) {
e.printStackTrace();
}
// 開始錄音
mRecorder.start(); // ①
recordBn.setEnabled(false);
stopBn.setEnabled(true);
} else if (sourceId == R.id.stop) {
if (soundFile != null && soundFile.exists()) {
// 停止錄音
mRecorder.stop(); // ②
// 釋放資源
mRecorder.release(); // ③
mRecorder = null;
recordBn.setEnabled(true);
stopBn.setEnabled(false);
}
}
};
// 為兩個(gè)按鈕的單擊事件綁定監(jiān)聽器
recordBn.setOnClickListener(listener);
stopBn.setOnClickListener(listener);
}
}
@Override
public void onDestroy() {
if (soundFile != null && soundFile.exists()) {
// 停止錄音
mRecorder.stop();
// 釋放資源
mRecorder.release();
mRecorder = null;
}
super.onDestroy();
}
}
錄制視頻短片
<uses-feature
android:name="android.hardware.camera"
android:required="false" />
<!-- 授予該程序錄制聲音的權(quán)限 -->
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<!-- 授予該程序使用攝像頭的權(quán)限 -->
<uses-permission android:name="android.permission.CAMERA" />
<!-- 授予使用外部存儲(chǔ)器的權(quán)限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
public class MainActivity extends AppCompatActivity {
private ImageButton recordBn;
private ImageButton stopBn;
// 系統(tǒng)的視頻文件
private File videoFile;
private MediaRecorder mRecorder;
// 顯示視頻預(yù)覽的SurfaceView
private SurfaceView sView;
// 記錄是否正在進(jìn)行錄制
private boolean isRecording;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 獲取程序界面中的兩個(gè)按鈕
recordBn = findViewById(R.id.record);
stopBn = findViewById(R.id.stop);
// 讓stopBn按鈕不可用
stopBn.setEnabled(false);
requestPermissions(new String[]{Manifest.permission.CAMERA,
Manifest.permission.RECORD_AUDIO,
Manifest.permission.WRITE_EXTERNAL_STORAGE}, 0x123);
}
@Override
public void onRequestPermissionsResult(int requestCode,
@NonNull String[] permissions, @NonNull int[] grantResults) {
if (requestCode == 0x123 && grantResults.length == 3
&& grantResults[0] == PackageManager.PERMISSION_GRANTED
&& grantResults[1] == PackageManager.PERMISSION_GRANTED
&& grantResults[2] == PackageManager.PERMISSION_GRANTED) {
View.OnClickListener listener = source ->
{
int sourceId = source.getId();
if (sourceId == R.id.record) {
// 創(chuàng)建保存錄制視頻的視頻文件
videoFile = new File(String.format("%s/%s.mp4", getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS).toString(), System.currentTimeMillis()));
// 創(chuàng)建MediaRecorder對(duì)象
mRecorder = new MediaRecorder();
mRecorder.reset();
// 設(shè)置從麥克風(fēng)采集聲音
mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
// 設(shè)置從攝像頭采集圖像
mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
// 設(shè)置視頻文件的輸出格式
// 必須在設(shè)置聲音編碼格式、圖像編碼格式之前設(shè)置
mRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
// 設(shè)置聲音編碼格式
mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
// 設(shè)置圖像編碼格式
mRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
// 設(shè)置視頻尺寸,此處要求攝像頭本身支持該尺寸,否則會(huì)在調(diào)用MediaRecorder的play方法時(shí)出現(xiàn)異常
// mRecorder.setVideoSize(640, 560);
mRecorder.setVideoSize(1920, 1080);
// 每秒 12幀
mRecorder.setVideoFrameRate(12);
mRecorder.setOutputFile(videoFile.getAbsolutePath());
// 指定使用SurfaceView來預(yù)覽視頻
mRecorder.setPreviewDisplay(sView.getHolder().getSurface()); // ①
try {
mRecorder.prepare();
} catch (IOException e) {
e.printStackTrace();
}
// 開始錄制
mRecorder.start();
System.out.println("---recording---");
// 讓recordBn按鈕不可用
recordBn.setEnabled(false);
// 讓stopBn按鈕可用
stopBn.setEnabled(true);
isRecording = true;
} else if (sourceId == R.id.stop) {
// 如果正在進(jìn)行錄制
if (isRecording) {
// 停止錄制
mRecorder.stop();
// 釋放資源
mRecorder.release();
mRecorder = null;
// 讓recordBn按鈕可用
recordBn.setEnabled(true);
// 讓stopBn按鈕不可用
stopBn.setEnabled(false);
}
}
};
// 為兩個(gè)按鈕的單擊事件綁定監(jiān)聽器
recordBn.setOnClickListener(listener);
stopBn.setOnClickListener(listener);
// 獲取程序界面中的SurfaceView
sView = findViewById(R.id.sView);
// 設(shè)置分辨率
sView.getHolder().setFixedSize(320, 280);
// 設(shè)置該組件讓屏幕不會(huì)自動(dòng)關(guān)閉
sView.getHolder().setKeepScreenOn(true);
}
}
}
layout/activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- 顯示視頻預(yù)覽的SurfaceView -->
<SurfaceView
android:id="@+id/sView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center|bottom"
android:gravity="center_horizontal"
android:orientation="horizontal">
<ImageButton
android:id="@+id/record"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/record" />
<ImageButton
android:id="@+id/stop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/stop" />
</LinearLayout>
</FrameLayout>
摘抄至《瘋狂Android講義(第4版)》