|
|
@ -17,13 +17,21 @@ import android.graphics.Color;
|
|
|
|
import android.graphics.Paint;
|
|
|
|
import android.graphics.Paint;
|
|
|
|
import android.graphics.Path;
|
|
|
|
import android.graphics.Path;
|
|
|
|
import android.graphics.RectF;
|
|
|
|
import android.graphics.RectF;
|
|
|
|
|
|
|
|
import android.media.MediaCodec;
|
|
|
|
|
|
|
|
import android.media.MediaCodecInfo;
|
|
|
|
|
|
|
|
import android.media.MediaCodecList;
|
|
|
|
|
|
|
|
import android.media.MediaFormat;
|
|
|
|
|
|
|
|
import android.media.MediaScannerConnection;
|
|
|
|
import android.os.Bundle;
|
|
|
|
import android.os.Bundle;
|
|
|
|
|
|
|
|
import android.os.Environment;
|
|
|
|
import android.os.Handler;
|
|
|
|
import android.os.Handler;
|
|
|
|
import android.os.Message;
|
|
|
|
import android.os.Message;
|
|
|
|
import android.provider.ContactsContract;
|
|
|
|
import android.provider.ContactsContract;
|
|
|
|
import android.util.AttributeSet;
|
|
|
|
import android.util.AttributeSet;
|
|
|
|
import android.util.Log;
|
|
|
|
import android.util.Log;
|
|
|
|
|
|
|
|
import android.view.LayoutInflater;
|
|
|
|
import android.view.MotionEvent;
|
|
|
|
import android.view.MotionEvent;
|
|
|
|
|
|
|
|
import android.view.Surface;
|
|
|
|
import android.view.View;
|
|
|
|
import android.view.View;
|
|
|
|
import android.view.ViewGroup;
|
|
|
|
import android.view.ViewGroup;
|
|
|
|
import android.view.animation.AlphaAnimation;
|
|
|
|
import android.view.animation.AlphaAnimation;
|
|
|
@ -35,19 +43,26 @@ import android.widget.ImageView;
|
|
|
|
import android.widget.TextView;
|
|
|
|
import android.widget.TextView;
|
|
|
|
import android.widget.Toast;
|
|
|
|
import android.widget.Toast;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import org.json.JSONException;
|
|
|
|
|
|
|
|
import org.json.JSONObject;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import java.io.BufferedOutputStream;
|
|
|
|
import java.io.ByteArrayInputStream;
|
|
|
|
import java.io.ByteArrayInputStream;
|
|
|
|
import java.io.ByteArrayOutputStream;
|
|
|
|
import java.io.ByteArrayOutputStream;
|
|
|
|
|
|
|
|
import java.io.File;
|
|
|
|
|
|
|
|
import java.io.FileOutputStream;
|
|
|
|
import java.io.IOException;
|
|
|
|
import java.io.IOException;
|
|
|
|
import java.net.DatagramPacket;
|
|
|
|
import java.net.DatagramPacket;
|
|
|
|
import java.net.DatagramSocket;
|
|
|
|
import java.net.DatagramSocket;
|
|
|
|
import java.net.InetAddress;
|
|
|
|
import java.net.InetAddress;
|
|
|
|
import java.net.*;
|
|
|
|
import java.net.*;
|
|
|
|
|
|
|
|
import java.nio.ByteBuffer;
|
|
|
|
import java.util.concurrent.ExecutorService;
|
|
|
|
import java.util.concurrent.ExecutorService;
|
|
|
|
import java.util.concurrent.Executors;
|
|
|
|
import java.util.concurrent.Executors;
|
|
|
|
|
|
|
|
|
|
|
|
import android.os.Bundle;
|
|
|
|
import android.os.Bundle;
|
|
|
|
import android.widget.ToggleButton;
|
|
|
|
import android.widget.ToggleButton;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public class VideoActivity extends AppCompatActivity {
|
|
|
|
public class VideoActivity extends AppCompatActivity {
|
|
|
|
private final static String SEND_to_IP = "192.168.39.47"; //填写接收方IP
|
|
|
|
private final static String SEND_to_IP = "192.168.39.47"; //填写接收方IP
|
|
|
|
private final static String Recieve_IP = "192.168.39.47";//填服务器IP,与send_to_IP为同一个
|
|
|
|
private final static String Recieve_IP = "192.168.39.47";//填服务器IP,与send_to_IP为同一个
|
|
|
@ -75,13 +90,19 @@ public class VideoActivity extends AppCompatActivity {
|
|
|
|
private ImageButton Setting_btn;
|
|
|
|
private ImageButton Setting_btn;
|
|
|
|
private ImageButton TakeOff_btn;
|
|
|
|
private ImageButton TakeOff_btn;
|
|
|
|
private ImageButton Landing_btn;
|
|
|
|
private ImageButton Landing_btn;
|
|
|
|
|
|
|
|
private ImageButton Record_btn;
|
|
|
|
private ToggleButton Mode_btn;
|
|
|
|
private ToggleButton Mode_btn;
|
|
|
|
|
|
|
|
private ImageButton selfHome_btn;
|
|
|
|
private String mangle;
|
|
|
|
private String mangle;
|
|
|
|
private float mdistance;
|
|
|
|
private float mdistance;
|
|
|
|
// 创建一个可缓存的线程池
|
|
|
|
// 创建一个可缓存的线程池
|
|
|
|
private ExecutorService mThreadPool = Executors.newCachedThreadPool();
|
|
|
|
private ExecutorService mThreadPool = Executors.newCachedThreadPool();
|
|
|
|
private UdpDataThread warning_thread;
|
|
|
|
private UdpDataThread warning_thread;
|
|
|
|
private TextView battery_warning;
|
|
|
|
private TextView battery_warning;
|
|
|
|
|
|
|
|
private ImageButton show_status;
|
|
|
|
|
|
|
|
private String batteryStatus="未获取";
|
|
|
|
|
|
|
|
private String speedStatus="未获取";
|
|
|
|
|
|
|
|
private String distanceStatus="未获取";
|
|
|
|
//ReceiveData()显示到imageView
|
|
|
|
//ReceiveData()显示到imageView
|
|
|
|
//manager部分:打开线程,接收
|
|
|
|
//manager部分:打开线程,接收
|
|
|
|
//model部分:发送视频流
|
|
|
|
//model部分:发送视频流
|
|
|
@ -102,8 +123,28 @@ public class VideoActivity extends AppCompatActivity {
|
|
|
|
TurnRight_btn = findViewById(R.id.rotate_right_button);
|
|
|
|
TurnRight_btn = findViewById(R.id.rotate_right_button);
|
|
|
|
TakeOff_btn = findViewById(R.id.takeoff_button);
|
|
|
|
TakeOff_btn = findViewById(R.id.takeoff_button);
|
|
|
|
Mode_btn = findViewById(R.id.toggleButton2);
|
|
|
|
Mode_btn = findViewById(R.id.toggleButton2);
|
|
|
|
|
|
|
|
Record_btn = findViewById(R.id.start_record_button);
|
|
|
|
Setting_btn = findViewById(R.id.setting_button);
|
|
|
|
Setting_btn = findViewById(R.id.setting_button);
|
|
|
|
|
|
|
|
Setting_btn.setOnClickListener(new View.OnClickListener() {
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
|
|
|
public void onClick(View v) {
|
|
|
|
|
|
|
|
Intent intent = new Intent(VideoActivity.this, SettingActivity.class);
|
|
|
|
|
|
|
|
startActivity(intent);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
selfHome_btn = findViewById(R.id.self_home);
|
|
|
|
|
|
|
|
selfHome_btn.setOnClickListener(new View.OnClickListener() {
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
|
|
|
public void onClick(View view) {
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
sendCommand("DIRECTHOME");
|
|
|
|
|
|
|
|
} catch (UnknownHostException e) {
|
|
|
|
|
|
|
|
throw new RuntimeException(e);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
battery_warning =findViewById(R.id.warning);
|
|
|
|
battery_warning =findViewById(R.id.warning);
|
|
|
|
|
|
|
|
show_status=findViewById(R.id.show_status_button);
|
|
|
|
battery_warning.setTextColor(Color.RED);
|
|
|
|
battery_warning.setTextColor(Color.RED);
|
|
|
|
Animation anim = new AlphaAnimation(0.0f, 1.0f);
|
|
|
|
Animation anim = new AlphaAnimation(0.0f, 1.0f);
|
|
|
|
anim.setDuration(500); // 闪烁时间间隔
|
|
|
|
anim.setDuration(500); // 闪烁时间间隔
|
|
|
@ -121,6 +162,13 @@ public class VideoActivity extends AppCompatActivity {
|
|
|
|
} catch (UnknownHostException e) {
|
|
|
|
} catch (UnknownHostException e) {
|
|
|
|
throw new RuntimeException(e);
|
|
|
|
throw new RuntimeException(e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
show_status.setOnClickListener(new View.OnClickListener() {
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
|
|
|
public void onClick(View v) {
|
|
|
|
|
|
|
|
// 在这里编写 ImageButton 的点击事件处理逻辑
|
|
|
|
|
|
|
|
showPopup(speedStatus,batteryStatus,distanceStatus);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
private void Control_Button_Init(){
|
|
|
|
private void Control_Button_Init(){
|
|
|
|
|
|
|
|
|
|
|
@ -147,16 +195,16 @@ public class VideoActivity extends AppCompatActivity {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
Forward_btn.setOnClickListener(new View.OnClickListener() {
|
|
|
|
Forward_btn.setOnClickListener(new View.OnClickListener() {
|
|
|
|
@Override
|
|
|
|
@Override
|
|
|
|
public void onClick(View v) {
|
|
|
|
public void onClick(View v) {
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
sendCommand("FORWARD");
|
|
|
|
sendCommand("FORWARD");
|
|
|
|
} catch (UnknownHostException e) {
|
|
|
|
} catch (UnknownHostException e) {
|
|
|
|
throw new RuntimeException(e);
|
|
|
|
throw new RuntimeException(e);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Log.i(TAG, "onClick: FFFFFFFForward");
|
|
|
|
Log.i(TAG, "onClick: FFFFFFFForward");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
Back_btn.setOnClickListener(new View.OnClickListener() {
|
|
|
|
Back_btn.setOnClickListener(new View.OnClickListener() {
|
|
|
|
@Override
|
|
|
|
@Override
|
|
|
|
public void onClick(View v) {
|
|
|
|
public void onClick(View v) {
|
|
|
@ -234,17 +282,10 @@ public class VideoActivity extends AppCompatActivity {
|
|
|
|
Log.i(TAG, "onClick: TTTTTTTTTTTTurnRRRRRRRRRRight");
|
|
|
|
Log.i(TAG, "onClick: TTTTTTTTTTTTurnRRRRRRRRRRight");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
Setting_btn.setOnClickListener(new View.OnClickListener() {
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
|
|
|
public void onClick(View v) {
|
|
|
|
|
|
|
|
Intent intent = new Intent(VideoActivity.this, SettingActivity.class);
|
|
|
|
|
|
|
|
startActivity(intent);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void Condition_Init() throws UnknownHostException {
|
|
|
|
private void Condition_Init() throws UnknownHostException {
|
|
|
|
sendCommand("AUTO");
|
|
|
|
|
|
|
|
ReceiveHandler receiveHandler = new ReceiveHandler();
|
|
|
|
ReceiveHandler receiveHandler = new ReceiveHandler();
|
|
|
|
UdpReceiveThread StreamThread = new UdpReceiveThread(Recieve_IP,RECEIVE_PORT,receiveHandler);
|
|
|
|
UdpReceiveThread StreamThread = new UdpReceiveThread(Recieve_IP,RECEIVE_PORT,receiveHandler);
|
|
|
|
try {
|
|
|
|
try {
|
|
|
@ -266,19 +307,22 @@ public class VideoActivity extends AppCompatActivity {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
// 执行功能1
|
|
|
|
// 执行功能1
|
|
|
|
try {
|
|
|
|
// try {
|
|
|
|
changetoAuto();
|
|
|
|
// changetoAuto();
|
|
|
|
} catch (UnknownHostException e) {
|
|
|
|
// } catch (UnknownHostException e) {
|
|
|
|
throw new RuntimeException(e);
|
|
|
|
// throw new RuntimeException(e);
|
|
|
|
}
|
|
|
|
// }
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
Record_btn.setOnClickListener(new View.OnClickListener() {
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
|
|
|
public void onClick(View view) {
|
|
|
|
|
|
|
|
saveVideo(bp);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void changetoAuto() throws UnknownHostException {
|
|
|
|
|
|
|
|
sendCommand("AUTO");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void changetoManual() throws UnknownHostException {
|
|
|
|
private void changetoManual() throws UnknownHostException {
|
|
|
|
sendCommand("STOP");
|
|
|
|
sendCommand("STOP");
|
|
|
@ -291,7 +335,10 @@ public class VideoActivity extends AppCompatActivity {
|
|
|
|
runOnUiThread(new Runnable() {
|
|
|
|
runOnUiThread(new Runnable() {
|
|
|
|
@Override
|
|
|
|
@Override
|
|
|
|
public void run() {
|
|
|
|
public void run() {
|
|
|
|
imgShow.setImageBitmap(bp);
|
|
|
|
int targetWidth = imgShow.getWidth();
|
|
|
|
|
|
|
|
int targetHeight = imgShow.getHeight();
|
|
|
|
|
|
|
|
Bitmap scaledBitmap = Bitmap.createScaledBitmap(bp, targetWidth, targetHeight, true);
|
|
|
|
|
|
|
|
imgShow.setImageBitmap(scaledBitmap);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -304,7 +351,6 @@ public class VideoActivity extends AppCompatActivity {
|
|
|
|
super.handleMessage(msg);
|
|
|
|
super.handleMessage(msg);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
/*
|
|
|
|
* UDP数据接受线程
|
|
|
|
* UDP数据接受线程
|
|
|
|
* */
|
|
|
|
* */
|
|
|
@ -375,7 +421,6 @@ public class VideoActivity extends AppCompatActivity {
|
|
|
|
// 创建 DatagramSocket 对象并发送数据报文
|
|
|
|
// 创建 DatagramSocket 对象并发送数据报文
|
|
|
|
DatagramSocket socket = new DatagramSocket();
|
|
|
|
DatagramSocket socket = new DatagramSocket();
|
|
|
|
socket.send(packet);
|
|
|
|
socket.send(packet);
|
|
|
|
|
|
|
|
|
|
|
|
// 关闭 DatagramSocket 对象
|
|
|
|
// 关闭 DatagramSocket 对象
|
|
|
|
socket.close();
|
|
|
|
socket.close();
|
|
|
|
} catch (IOException e) {
|
|
|
|
} catch (IOException e) {
|
|
|
@ -393,14 +438,14 @@ public class VideoActivity extends AppCompatActivity {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
/*
|
|
|
|
*UDP数据接收线程
|
|
|
|
*UDP数据接收线程
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
public class UdpDataThread extends Thread {
|
|
|
|
public class UdpDataThread extends Thread {
|
|
|
|
private DatagramSocket socket;
|
|
|
|
private DatagramSocket socket;
|
|
|
|
private boolean running;
|
|
|
|
private boolean running;
|
|
|
|
private byte[] buffer;
|
|
|
|
private byte[] buffer;
|
|
|
|
private static final int BUFFER_SIZE = 1024; // 设置接收缓冲区大小
|
|
|
|
private static final int BUFFER_SIZE = 1024; // 设置接收缓冲区大小
|
|
|
|
|
|
|
|
private JSONObject jsonObject;
|
|
|
|
public UdpDataThread() {
|
|
|
|
public UdpDataThread() {
|
|
|
|
buffer = new byte[BUFFER_SIZE];
|
|
|
|
buffer = new byte[BUFFER_SIZE];
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -408,21 +453,26 @@ public class VideoActivity extends AppCompatActivity {
|
|
|
|
@Override
|
|
|
|
@Override
|
|
|
|
public void run() {
|
|
|
|
public void run() {
|
|
|
|
running = true;
|
|
|
|
running = true;
|
|
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
try {
|
|
|
|
socket = new DatagramSocket(6666); // 设置接收端口号
|
|
|
|
socket = new DatagramSocket(6666); // 设置接收端口号
|
|
|
|
while (running) {
|
|
|
|
while (running) {
|
|
|
|
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
|
|
|
|
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
|
|
|
|
socket.receive(packet);
|
|
|
|
socket.receive(packet);
|
|
|
|
String receivedData = new String(packet.getData(), 0, packet.getLength());
|
|
|
|
String receivedData = new String(packet.getData(), 0, packet.getLength(), "UTF-8");
|
|
|
|
if (receivedData.equals("电量低于10%")) {
|
|
|
|
jsonObject = new JSONObject(receivedData);
|
|
|
|
battery_warning.setText(receivedData);}else{
|
|
|
|
batteryStatus = jsonObject.getString("battery");
|
|
|
|
|
|
|
|
speedStatus = jsonObject.getString("speed");
|
|
|
|
|
|
|
|
distanceStatus = jsonObject.getString("distance");
|
|
|
|
|
|
|
|
if (batteryStatus.equals("10")) {
|
|
|
|
|
|
|
|
battery_warning.setText("电量仅剩"+batteryStatus);}else{
|
|
|
|
battery_warning.setText("");
|
|
|
|
battery_warning.setText("");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
System.out.println("接收到数据:" + receivedData);
|
|
|
|
System.out.println("接收到数据:" + batteryStatus);
|
|
|
|
|
|
|
|
System.out.println("接收到数据:" + speedStatus);
|
|
|
|
|
|
|
|
System.out.println("接收到数据:" + distanceStatus);
|
|
|
|
// 在这里处理收到的数据,可以根据实际需求进行解析或其他操作
|
|
|
|
// 在这里处理收到的数据,可以根据实际需求进行解析或其他操作
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} catch (IOException e) {
|
|
|
|
} catch (IOException | JSONException e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
e.printStackTrace();
|
|
|
|
} finally {
|
|
|
|
} finally {
|
|
|
|
if (socket != null) {
|
|
|
|
if (socket != null) {
|
|
|
@ -435,43 +485,129 @@ public class VideoActivity extends AppCompatActivity {
|
|
|
|
running = false;
|
|
|
|
running = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//初始化UDP发送线程
|
|
|
|
|
|
|
|
// private static void sendCommand(String Sendstr) throws UnknownHostException {
|
|
|
|
private String findEncoderCodecName(String mimeType) {
|
|
|
|
// InetAddress sendIP = InetAddress.getByName(SEND_to_IP); // 目标 IP 地址
|
|
|
|
MediaCodecList codecList = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
|
|
|
|
// int sendPort = 8888; // 目标端口号
|
|
|
|
int numCodecs = codecList.getCodecInfos().length;
|
|
|
|
// byte[] sendData = Sendstr.getBytes(); // 要发送的数据
|
|
|
|
for (int i = 0; i < numCodecs; i++) {
|
|
|
|
// UdpSendThread sendCommandThread = new UdpSendThread(sendIP, sendPort, sendData); // 创建新的线程对象
|
|
|
|
MediaCodecInfo codecInfo = MediaCodecList.getCodecInfoAt(i);
|
|
|
|
// sendCommandThread.start(); // 启动线程发送数据
|
|
|
|
if (!codecInfo.isEncoder()) {
|
|
|
|
// }
|
|
|
|
continue;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
String[] types = codecInfo.getSupportedTypes();
|
|
|
|
|
|
|
|
for (String type : types) {
|
|
|
|
|
|
|
|
if (type.equalsIgnoreCase(mimeType)) {
|
|
|
|
|
|
|
|
return codecInfo.getName();
|
|
|
|
//设置按钮
|
|
|
|
}
|
|
|
|
// public void showDialog(View view) {
|
|
|
|
}
|
|
|
|
// Dialog dialog = new Dialog(VideoActivity.this);
|
|
|
|
}
|
|
|
|
// dialog.setContentView(R.layout.dialog_takeoff);
|
|
|
|
return null;
|
|
|
|
//
|
|
|
|
}
|
|
|
|
// SlideUnlockView slideUnlockView = (SlideUnlockView) dialog.findViewById(R.id.slide_unlock_view);
|
|
|
|
|
|
|
|
// slideUnlockView.setOnUnlockListener(new SlideUnlockView.OnUnlockListener() {
|
|
|
|
MediaCodec codec;
|
|
|
|
// @Override
|
|
|
|
private void saveVideo(Bitmap videoBitmap) {
|
|
|
|
// public void onUnlock() {
|
|
|
|
try {
|
|
|
|
// // 在用户滑动解锁后执行操作
|
|
|
|
String codecName = findEncoderCodecName(MediaFormat.MIMETYPE_VIDEO_AVC);
|
|
|
|
//// try {
|
|
|
|
if (codecName != null) {
|
|
|
|
//// sendCommand("TAKEOFF"+"___"+angle+"___"+String.valueOf(distance));
|
|
|
|
codec = MediaCodec.createByCodecName(codecName);
|
|
|
|
//// } catch (UnknownHostException e) {
|
|
|
|
|
|
|
|
//// throw new RuntimeException(e);
|
|
|
|
// 根据视频尺寸设置编码器参数
|
|
|
|
//// }
|
|
|
|
MediaFormat format = MediaFormat.createVideoFormat(MediaFormat.MIMETYPE_VIDEO_AVC, videoBitmap.getWidth(), videoBitmap.getHeight());
|
|
|
|
// UdpReceiveThread udpReceiveThread = new UdpReceiveThread();
|
|
|
|
format.setInteger(MediaFormat.KEY_BIT_RATE, 2000000);
|
|
|
|
// udpReceiveThread.start();
|
|
|
|
format.setInteger(MediaFormat.KEY_FRAME_RATE, 30);
|
|
|
|
//
|
|
|
|
format.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface);
|
|
|
|
// Log.i(TAG, "onClick: 2222222222222222222222222");
|
|
|
|
format.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 1);
|
|
|
|
//
|
|
|
|
|
|
|
|
// }
|
|
|
|
// 配置编码器并启动
|
|
|
|
// });
|
|
|
|
codec.configure(format, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);
|
|
|
|
// dialog.show();
|
|
|
|
Surface inputSurface = codec.createInputSurface();
|
|
|
|
// }
|
|
|
|
codec.start();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 创建保存视频的路径和文件名
|
|
|
|
|
|
|
|
String fileName = "video_" + System.currentTimeMillis() + ".mp4";
|
|
|
|
|
|
|
|
String filePath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES) + "/" + fileName;
|
|
|
|
|
|
|
|
File videoFile = new File(filePath);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
FileOutputStream fileOutputStream = new FileOutputStream(videoFile);
|
|
|
|
|
|
|
|
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 循环编码每一帧
|
|
|
|
|
|
|
|
boolean isInputDone = false;
|
|
|
|
|
|
|
|
boolean isOutputDone = false;
|
|
|
|
|
|
|
|
while (!isOutputDone) {
|
|
|
|
|
|
|
|
if (!isInputDone) {
|
|
|
|
|
|
|
|
int index = codec.dequeueInputBuffer(10000);
|
|
|
|
|
|
|
|
if (index >= 0) {
|
|
|
|
|
|
|
|
ByteBuffer inputBuffer = codec.getInputBuffer(index);
|
|
|
|
|
|
|
|
inputBuffer.clear();
|
|
|
|
|
|
|
|
Canvas canvas = inputSurface.lockCanvas(null);
|
|
|
|
|
|
|
|
canvas.drawBitmap(videoBitmap, 0, 0, null);
|
|
|
|
|
|
|
|
inputSurface.unlockCanvasAndPost(canvas);
|
|
|
|
|
|
|
|
codec.queueInputBuffer(index, 0, 0, 0, MediaCodec.BUFFER_FLAG_END_OF_STREAM);
|
|
|
|
|
|
|
|
isInputDone = true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();
|
|
|
|
|
|
|
|
int outputIndex = codec.dequeueOutputBuffer(bufferInfo, 10000);
|
|
|
|
|
|
|
|
if (outputIndex >= 0) {
|
|
|
|
|
|
|
|
ByteBuffer outputBuffer = codec.getOutputBuffer(outputIndex);
|
|
|
|
|
|
|
|
byte[] outData = new byte[bufferInfo.size];
|
|
|
|
|
|
|
|
outputBuffer.get(outData);
|
|
|
|
|
|
|
|
bufferedOutputStream.write(outData);
|
|
|
|
|
|
|
|
codec.releaseOutputBuffer(outputIndex, false);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ((bufferInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
|
|
|
|
|
|
|
|
isOutputDone = true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 关闭文件流
|
|
|
|
|
|
|
|
bufferedOutputStream.flush();
|
|
|
|
|
|
|
|
bufferedOutputStream.close();
|
|
|
|
|
|
|
|
fileOutputStream.close();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 通知媒体库更新文件
|
|
|
|
|
|
|
|
MediaScannerConnection.scanFile(this, new String[]{videoFile.getAbsolutePath()}, null, null);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Toast.makeText(this, "视频保存成功", Toast.LENGTH_SHORT).show();
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
Toast.makeText(this, "无法找到支持的视频编码器", Toast.LENGTH_SHORT).show();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
} catch (IOException e) {
|
|
|
|
|
|
|
|
e.printStackTrace();
|
|
|
|
|
|
|
|
} finally {
|
|
|
|
|
|
|
|
if (codec != null) {
|
|
|
|
|
|
|
|
codec.stop();
|
|
|
|
|
|
|
|
codec.release();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void showPopup(String speedStatus,String batteryStatus,String distanceStatus) {
|
|
|
|
|
|
|
|
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
|
|
|
|
|
|
|
LayoutInflater inflater = getLayoutInflater();
|
|
|
|
|
|
|
|
View dialogView = inflater.inflate(R.layout.custom_dialog, null);
|
|
|
|
|
|
|
|
TextView speedstatus = dialogView.findViewById(R.id.speed);
|
|
|
|
|
|
|
|
speedstatus.setText("当前速度为:"+speedStatus);
|
|
|
|
|
|
|
|
TextView batterystatus = dialogView.findViewById(R.id.battery);
|
|
|
|
|
|
|
|
batterystatus.setText("当前电量为:"+batteryStatus);
|
|
|
|
|
|
|
|
TextView distancestatus = dialogView.findViewById(R.id.distance);
|
|
|
|
|
|
|
|
distancestatus.setText("当前距离为:"+distanceStatus);
|
|
|
|
|
|
|
|
builder.setView(dialogView);
|
|
|
|
|
|
|
|
builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
|
|
|
public void onClick(DialogInterface dialog, int which) {
|
|
|
|
|
|
|
|
// 点击确定按钮后的操作
|
|
|
|
|
|
|
|
dialog.dismiss();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
AlertDialog dialog = builder.create();
|
|
|
|
|
|
|
|
dialog.show();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//////////////////////////////滑动开关//////////////////////////////
|
|
|
|
//////////////////////////////滑动开关//////////////////////////////
|
|
|
|
public static class SlideUnlockView extends View{
|
|
|
|
public static class SlideUnlockView extends View{
|
|
|
|
|
|
|
|
|
|
|
@ -653,4 +789,25 @@ public class VideoActivity extends AppCompatActivity {
|
|
|
|
return super.onTouchEvent(event);
|
|
|
|
return super.onTouchEvent(event);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void shutdown(){
|
|
|
|
|
|
|
|
warning_thread.stopThread();
|
|
|
|
|
|
|
|
mThreadPool.shutdownNow();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
|
|
|
public void onBackPressed() {
|
|
|
|
|
|
|
|
// 返回到 MainActivity
|
|
|
|
|
|
|
|
shutdown();
|
|
|
|
|
|
|
|
Intent intent = new Intent(this, MainActivity.class);
|
|
|
|
|
|
|
|
startActivity(intent);
|
|
|
|
|
|
|
|
finish(); // 结束 VideoActivity
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
|
|
|
protected void onDestroy() {
|
|
|
|
|
|
|
|
super.onDestroy();
|
|
|
|
|
|
|
|
// 关闭线程
|
|
|
|
|
|
|
|
shutdown();
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|