Android - 录屏+上传视频
生活随笔
收集整理的這篇文章主要介紹了
Android - 录屏+上传视频
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
說明:
? ? demo要求是錄屏后上傳視頻到服務(wù)器。
? ? demo下載地址:點(diǎn)擊打開鏈接
1、重要代碼
1.0、先加上權(quán)限申請
<uses-permission android:name="android.permission.INTERNET" /><uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /><uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/><uses-permission android:name="android.permission.RECORD_AUDIO"/>?
1.1、申請視頻和存儲權(quán)限
//請求視頻和存儲權(quán)限private void requestPermission() {if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED) {ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, STORAGE_REQUEST_CODE);}if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.RECORD_AUDIO)!= PackageManager.PERMISSION_GRANTED) {ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.RECORD_AUDIO}, AUDIO_REQUEST_CODE);}} @Overridepublic void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {super.onRequestPermissionsResult(requestCode, permissions, grantResults);if (requestCode == STORAGE_REQUEST_CODE || requestCode == AUDIO_REQUEST_CODE) {if (grantResults[0] != PackageManager.PERMISSION_GRANTED) {finish();}}}1.2、申請錄屏和建立錄屏服務(wù)
Intent intent = new Intent(this, RecordService.class);bindService(intent, connection, BIND_AUTO_CREATE); //錄屏權(quán)限同意后返回@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {if (requestCode == RECORD_REQUEST_CODE && resultCode == RESULT_OK) {mediaProjection = projectionManager.getMediaProjection(resultCode, data);recordService.setMediaProject(mediaProjection);recordService.startRecord();startBtn.setText(R.string.stop_record);//設(shè)置文字countTimer();//開始計時openZFB();//打開支付寶luPinStatus = true;//設(shè)置錄屏狀態(tài)為true}} //建立錄屏服務(wù)private ServiceConnection connection = new ServiceConnection() {@Overridepublic void onServiceConnected(ComponentName className, IBinder service) {DisplayMetrics metrics = new DisplayMetrics();getWindowManager().getDefaultDisplay().getMetrics(metrics);RecordService.RecordBinder binder = (RecordService.RecordBinder) service;recordService = binder.getRecordService();recordService.setConfig(metrics.widthPixels, metrics.heightPixels, metrics.densityDpi);startBtn.setEnabled(true);startBtn.setText(recordService.isRunning() ? R.string.stop_record : R.string.start_record);}@Overridepublic void onServiceDisconnected(ComponentName arg0) {}};2、完整代碼
1、RecordApplication.java
package com.baofu.lupin;import android.app.Application; import android.content.Context; import android.content.Intent;/*** Created by BF100165 on 2018/6/21.*/public class RecordApplication extends Application {private static RecordApplication application;@Overrideprotected void attachBaseContext(Context base) {super.attachBaseContext(base);application = this;}@Overridepublic void onCreate() {super.onCreate();// 啟動 Marvel servicestartService(new Intent(this, RecordService.class));}public static RecordApplication getInstance() {return application;} }2、AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android"package="com.baofu.lupin"><uses-permission android:name="android.permission.INTERNET" /><uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /><uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/><uses-permission android:name="android.permission.RECORD_AUDIO"/><applicationandroid:name=".RecordApplication"android:allowBackup="true"android:icon="@mipmap/ic_launcher"android:label="@string/app_name"android:supportsRtl="true"android:theme="@style/AppTheme"><activityandroid:name=".MainActivity"android:label="@string/app_name"android:theme="@style/AppTheme.NoActionBar"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity><service android:name=".RecordService"/></application></manifest>3、MainActivity.java
package com.baofu.lupin;import android.Manifest; import android.content.ActivityNotFoundException; import android.content.ComponentName; import android.content.Intent; import android.content.ServiceConnection; import android.content.pm.PackageManager; import android.hardware.display.DisplayManager; import android.hardware.display.VirtualDisplay; import android.media.projection.MediaProjection; import android.media.projection.MediaProjectionManager; import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.os.CountDownTimer; import android.os.Environment; import android.os.IBinder; import android.support.annotation.RequiresApi; import android.support.design.widget.FloatingActionButton; import android.support.design.widget.Snackbar; import android.support.v4.app.ActivityCompat; import android.support.v4.content.ContextCompat; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; import android.text.TextUtils; import android.util.DisplayMetrics; import android.util.Log; import android.view.View; import android.view.Menu; import android.view.MenuItem; import android.widget.Button; import android.widget.TextView; import android.widget.Toast;import java.io.BufferedReader; import java.io.File; import java.io.InputStreamReader; import java.io.OutputStream; import java.net.HttpURLConnection; import java.net.URL; import java.util.HashMap; import java.util.Map;public class MainActivity extends AppCompatActivity {private static final int RECORD_REQUEST_CODE = 101;private static final int STORAGE_REQUEST_CODE = 102;private static final int AUDIO_REQUEST_CODE = 103;private MediaProjectionManager projectionManager;private MediaProjection mediaProjection;private RecordService recordService;private Button startBtn;private TextView tv_timer;private TextView btn_upload;private CountDownTimer timer;private boolean luPinStatus = false;//錄屏狀態(tài)初始為false@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);projectionManager = (MediaProjectionManager) getSystemService(MEDIA_PROJECTION_SERVICE);setContentView(R.layout.activity_main);Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);setSupportActionBar(toolbar);startBtn = (Button) findViewById(R.id.start_record);tv_timer = (TextView) findViewById(R.id.tv_timer);btn_upload = (TextView) findViewById(R.id.btn_upload);//開始錄屏startBtn.setEnabled(false);startBtn.setOnClickListener(new View.OnClickListener() {@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)@Overridepublic void onClick(View v) {if (recordService != null && recordService.isRunning()) {recordService.stopRecord();//結(jié)束錄屏startBtn.setText(R.string.start_record);timer.cancel();//結(jié)束計時luPinStatus = false;//錄屏狀態(tài)為false} else {Intent captureIntent = projectionManager.createScreenCaptureIntent();startActivityForResult(captureIntent, RECORD_REQUEST_CODE);}}});//上傳視頻btn_upload.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {if(luPinStatus) {Toast.makeText(MainActivity.this, "請先結(jié)束錄屏", Toast.LENGTH_SHORT).show();return;}final String filePath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + "ScreenRecord" + "/123456.mp4";File file = new File(filePath);final String url = "http://10.0.19.48/creditApi/video";if(!file.exists()) {Toast.makeText(MainActivity.this, "請先錄屏芝麻信用", Toast.LENGTH_SHORT).show();return;}new Thread(new Runnable() {@Overridepublic void run() {try {UploadUtils.uploadFile(MainActivity.this, btn_upload, tv_timer, url, filePath);} catch (Exception e) {e.printStackTrace();}}}).start();}});Intent intent = new Intent(this, RecordService.class);bindService(intent, connection, BIND_AUTO_CREATE);requestPermission();}//請求視頻和存儲權(quán)限private void requestPermission() {if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED) {ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, STORAGE_REQUEST_CODE);}if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.RECORD_AUDIO)!= PackageManager.PERMISSION_GRANTED) {ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.RECORD_AUDIO}, AUDIO_REQUEST_CODE);}}@Overrideprotected void onDestroy() {super.onDestroy();unbindService(connection);}//錄屏權(quán)限同意后返回@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {if (requestCode == RECORD_REQUEST_CODE && resultCode == RESULT_OK) {mediaProjection = projectionManager.getMediaProjection(resultCode, data);recordService.setMediaProject(mediaProjection);recordService.startRecord();startBtn.setText(R.string.stop_record);//設(shè)置文字countTimer();//開始計時openZFB();//打開支付寶luPinStatus = true;//設(shè)置錄屏狀態(tài)為true}}@Overridepublic void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {super.onRequestPermissionsResult(requestCode, permissions, grantResults);if (requestCode == STORAGE_REQUEST_CODE || requestCode == AUDIO_REQUEST_CODE) {if (grantResults[0] != PackageManager.PERMISSION_GRANTED) {finish();}}}//建立錄屏服務(wù)private ServiceConnection connection = new ServiceConnection() {@Overridepublic void onServiceConnected(ComponentName className, IBinder service) {DisplayMetrics metrics = new DisplayMetrics();getWindowManager().getDefaultDisplay().getMetrics(metrics);RecordService.RecordBinder binder = (RecordService.RecordBinder) service;recordService = binder.getRecordService();recordService.setConfig(metrics.widthPixels, metrics.heightPixels, metrics.densityDpi);startBtn.setEnabled(true);startBtn.setText(recordService.isRunning() ? R.string.stop_record : R.string.start_record);}@Overridepublic void onServiceDisconnected(ComponentName arg0) {}};//界面倒計時private void countTimer() {/** 倒計時60秒,一次1秒 */timer = new CountDownTimer(60 * 1000, 1000) {@Overridepublic void onTick(long millisUntilFinished) {// TODO Auto-generated method stubtv_timer.setText("還剩" + millisUntilFinished / 1000 + "秒");}@Overridepublic void onFinish() {tv_timer.setText("倒計時完畢了");}}.start();}//打開支付寶private void openZFB() {try {PackageManager packageManager= this.getApplicationContext().getPackageManager();Intent intent = packageManager.getLaunchIntentForPackage("com.eg.android.AlipayGphone");startActivity(intent);} catch (Exception e) {String url = "https://ds.alipay.com/?from=mobileweb";Intent intent = new Intent(Intent.ACTION_VIEW);intent.setData(Uri.parse(url));startActivity(intent);}}@Overridepublic boolean onCreateOptionsMenu(Menu menu) {// Inflate the menu; this adds items to the action bar if it is present.getMenuInflater().inflate(R.menu.menu_main, menu);return true;}@Overridepublic boolean onOptionsItemSelected(MenuItem item) {// Handle action bar item clicks here. The action bar will// automatically handle clicks on the Home/Up button, so long// as you specify a parent activity in AndroidManifest.xml.int id = item.getItemId();//noinspection SimplifiableIfStatementif (id == R.id.action_settings) {return true;}return super.onOptionsItemSelected(item);} }main.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"app:layout_behavior="@string/appbar_scrolling_view_behavior"tools:context="com.baofu.lupin.MainActivity"tools:showIn="@layout/activity_main"><LinearLayoutandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerInParent="true"android:orientation="vertical"><TextViewandroid:id="@+id/tv_timer"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:text="倒計時 - 打開支付寶" /></LinearLayout><LinearLayoutandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentBottom="true"android:layout_centerHorizontal="true"android:orientation="vertical"><Buttonandroid:id="@+id/btn_upload"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="上傳錄屏"/><Buttonandroid:id="@+id/start_record"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:layout_marginBottom="10dp"android:text="@string/start_record"/></LinearLayout> </RelativeLayout>strings.xml
<resources><string name="app_name">錄屏</string><string name="action_settings">Settings</string><string name="start_record">開始錄屏</string><string name="stop_record">停止錄屏</string> </resources>?
3、RecordService.java
package com.baofu.lupin;import android.annotation.TargetApi; import android.app.Service; import android.content.Intent; import android.hardware.display.DisplayManager; import android.hardware.display.VirtualDisplay; import android.media.MediaRecorder; import android.media.projection.MediaProjection; import android.os.Binder; import android.os.Build; import android.os.Environment; import android.os.HandlerThread; import android.os.IBinder; import android.widget.Toast;import java.io.File; import java.io.IOException;/*** 錄屏服務(wù)* Created by BF100165 on 2018/6/21.*/public class RecordService extends Service {private MediaProjection mediaProjection;private MediaRecorder mediaRecorder;private VirtualDisplay virtualDisplay;private boolean running;private int width = 720;private int height = 1080;private int dpi;@Overridepublic IBinder onBind(Intent intent) {return new RecordBinder();}@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {return START_STICKY;}@Overridepublic void onCreate() {super.onCreate();HandlerThread serviceThread = new HandlerThread("service_thread",android.os.Process.THREAD_PRIORITY_BACKGROUND);serviceThread.start();running = false;mediaRecorder = new MediaRecorder();}@Overridepublic void onDestroy() {super.onDestroy();}public void setMediaProject(MediaProjection project) {mediaProjection = project;}public boolean isRunning() {return running;}public void setConfig(int width, int height, int dpi) {this.width = width;this.height = height;this.dpi = dpi;}public boolean startRecord() {if (mediaProjection == null || running) {return false;}initRecorder();createVirtualDisplay();mediaRecorder.start();running = true;return true;}@TargetApi(Build.VERSION_CODES.LOLLIPOP)public boolean stopRecord() {if (!running) {return false;}running = false;mediaRecorder.stop();mediaRecorder.reset();virtualDisplay.release();mediaProjection.stop();return true;}@TargetApi(Build.VERSION_CODES.LOLLIPOP)private void createVirtualDisplay() {virtualDisplay = mediaProjection.createVirtualDisplay("MainScreen", width, height, dpi,DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR, mediaRecorder.getSurface(), null, null);}private void initRecorder() {mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);mediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);mediaRecorder.setOutputFile(getsaveDirectory() + "123456" + ".mp4");mediaRecorder.setVideoSize(width, height);mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);mediaRecorder.setVideoEncodingBitRate(5 * 1024 * 1024);mediaRecorder.setVideoFrameRate(30);try {mediaRecorder.prepare();} catch (IOException e) {e.printStackTrace();}}public String getsaveDirectory() {if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {String rootDir = Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + "ScreenRecord" + "/";File file = new File(rootDir);if (!file.exists()) {if (!file.mkdirs()) {return null;}}Toast.makeText(getApplicationContext(), rootDir, Toast.LENGTH_SHORT).show();return rootDir;} else {return null;}}public class RecordBinder extends Binder {public RecordService getRecordService() {return RecordService.this;}} }4、UploadUtils.java
package com.baofu.lupin;import android.app.Activity; import android.content.Context; import android.util.Log; import android.widget.TextView;import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; import java.net.URLEncoder; import java.util.HashMap; import java.util.Map;/*** 上傳視頻*/ public class UploadUtils {public static String uploadFile(Activity activity, final TextView btn, final TextView content, String serverUrl, final String localFilePath) throws Exception {activity.runOnUiThread(new Runnable() {@Overridepublic void run() {btn.setText("上傳中...");Log.e("上傳視頻", "地址:" + localFilePath);}});File file = new File(localFilePath);Map<String, Object> postDataParams = new HashMap<>();postDataParams.put("api_key", "asdfasf");postDataParams.put("video_type", "android");postDataParams.put("fileName", file.getName());URL url = new URL(serverUrl + "?" + getPostDataString(postDataParams));HttpURLConnection conn = (HttpURLConnection) url.openConnection();conn.setDoOutput(true);conn.setUseCaches(false);conn.setRequestMethod("POST");conn.setRequestProperty("Content-Type", "text/html");conn.setRequestProperty("Cache-Control", "no-cache");conn.setRequestProperty("Charsert", "UTF-8");conn.connect();conn.setConnectTimeout(20000);DataOutputStream out = new DataOutputStream(conn.getOutputStream());DataInputStream in = new DataInputStream(new FileInputStream(file));int bytes = 0;byte[] bufferOut = new byte[2048];while ((bytes = in.read(bufferOut)) != -1) {out.write(bufferOut, 0, bytes);}in.close();out.flush();out.close();InputStream inputStream = conn.getInputStream();final String respStr = getRespString(inputStream);activity.runOnUiThread(new Runnable() {@Overridepublic void run() {btn.setText("上傳完成-點(diǎn)擊繼續(xù)上傳");content.setText(respStr);Log.e("上傳視頻", "返回:" + respStr);}});conn.disconnect();return respStr;}public static String getPostDataString(Map<String, Object> params) throws Exception {StringBuilder result = new StringBuilder();boolean first = true;for (Map.Entry<String, Object> entry : params.entrySet()) {String key = entry.getKey();Object value = entry.getValue();if (first)first = false;elseresult.append("&");result.append(URLEncoder.encode(key, "UTF-8"));result.append("=");result.append(URLEncoder.encode(value.toString(), "UTF-8"));}return result.toString();}public static String getRespString(InputStream is) throws Exception {StringBuffer strBuf = new StringBuffer();byte[] bytes = new byte[4096];int r = 0;while ((r = is.read(bytes)) > 0) {strBuf.append(new String(bytes, 0, r, "UTF-8"));}return strBuf.toString();}}?
?
?
?
?
總結(jié)
以上是生活随笔為你收集整理的Android - 录屏+上传视频的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 商城系统答辩题目
- 下一篇: Android RecyclerView