From 2e9c929373de6476d3b54c9ac2bba0f48e99ef03 Mon Sep 17 00:00:00 2001 From: XiaoYan Date: Wed, 4 Aug 2021 19:01:08 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E6=94=B9=E8=A7=86=E9=A2=91?= =?UTF-8?q?=E6=8B=8D=E6=91=84=E6=B5=81=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle | 2 +- .../outdoor/activity/PictureActivity.java | 164 ++++++++++-------- .../outdoor/fragment/RoadFragment.java | 133 +++++++++----- .../outdoor/util/AWMp4ParserHelper.java | 32 ++++ app/src/main/res/layout/activity_picture.xml | 1 + 5 files changed, 216 insertions(+), 116 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 43917f5..e9775a3 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -3,7 +3,7 @@ apply plugin: 'com.android.application' android { compileSdkVersion 29 buildToolsVersion '29.0.2' - ndkVersion '23.0.7123448' + ndkVersion '21.0.6113669' defaultConfig { applicationId "com.navinfo.outdoor" diff --git a/app/src/main/java/com/navinfo/outdoor/activity/PictureActivity.java b/app/src/main/java/com/navinfo/outdoor/activity/PictureActivity.java index 85fa795..04154ff 100644 --- a/app/src/main/java/com/navinfo/outdoor/activity/PictureActivity.java +++ b/app/src/main/java/com/navinfo/outdoor/activity/PictureActivity.java @@ -98,7 +98,7 @@ public class PictureActivity extends BaseActivity implements View.OnClickListene private Button btnVideo, stopVideo; private String finalVideoPath; // 摄像后最终保存的文件名 - private File tmpFile; // 合并文件的临时文件路径 +// private File tmpFile; // 合并文件的临时文件路径 private Timer timer; private CsvTimerTask timerTask; // 执行定时写入csv文件的task private DateFormat formatter; @@ -109,7 +109,7 @@ public class PictureActivity extends BaseActivity implements View.OnClickListene @Override protected int getLayout() { EventBus.getDefault().register(this); - tmpFile = new File(Constant.PICTURE_FOLDER, "temp.mp4"); +// tmpFile = new File(Constant.PICTURE_FOLDER, "temp.mp4"); formatter = new SimpleDateFormat("yyyyMMdd HHmmss"); return R.layout.activity_picture; } @@ -121,9 +121,9 @@ public class PictureActivity extends BaseActivity implements View.OnClickListene if (getIntent()!=null) { finalVideoPath = getIntent().getStringExtra(Constant.INTENT_VIDEO_PATH); } - if (finalVideoPath == null) { - finalVideoPath = Constant.PICTURE_FOLDER+"/final.mp4"; - } +// if (finalVideoPath == null) { +// finalVideoPath = Constant.PICTURE_FOLDER+"/final.mp4"; +// } layerChange = findViewById(R.id.layer_change); @@ -145,12 +145,13 @@ public class PictureActivity extends BaseActivity implements View.OnClickListene @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { if (isChecked) { // 开始采集,设置按钮文字内容为“结束采集” - captureVideo.setText("暂停采集"); + captureVideo.setText("结束采集"); // stopVideo.setEnabled(false);// 开始采集视频后,禁用停止采集的按钮,必须暂停采集后才可点击停止采集 startTakenVideo(); // 开始采集视频 } else { - stopTakenVideo(); +// stopTakenVideo(); captureVideo.setText("开始采集"); + stopVideoAndFinish(); } } }); @@ -232,45 +233,49 @@ public class PictureActivity extends BaseActivity implements View.OnClickListene super.onVideoTaken(result); Toast.makeText(PictureActivity.this, "暂停摄像", Toast.LENGTH_SHORT).show(); showLoadingDialog(); - new Thread(new Runnable() { - @Override - public void run() { - if (result!=null) { - File currentFile = result.getFile(); - if (finalVideoPath!=null) { // 有指定的视频文件名称,合并文件 - if (new File(finalVideoPath).exists()) { - List spliteFileList = new ArrayList<>(); - spliteFileList.add(finalVideoPath); - spliteFileList.add(currentFile.getAbsolutePath()); - try { - AWMp4ParserHelper.getInstance().mergeVideos(spliteFileList, tmpFile.getAbsolutePath()); - if (tmpFile.exists()) { - File finalVideoFile = new File(finalVideoPath); - finalVideoFile.delete(); - currentFile.delete(); - tmpFile.renameTo(finalVideoFile); - } else { - Toast.makeText(PictureActivity.this, "视频合并失败!", Toast.LENGTH_SHORT).show(); - } - } catch (Exception e) { - Log.e("PictureActivity", e.getMessage()); - } - } else { - currentFile.renameTo(new File(finalVideoPath)); - } - } - } - runOnUiThread(new Runnable() { - @Override - public void run() { - dismissLoadingDialog(); - if (isFinishActivity) { - PictureActivity.this.finish(); - } - } - }); - } - }).start(); + dismissLoadingDialog(); + if (isFinishActivity) { + PictureActivity.this.finish(); + } +// new Thread(new Runnable() { +// @Override +// public void run() { +// if (result!=null) { +// File currentFile = result.getFile(); +// if (finalVideoPath!=null) { // 有指定的视频文件名称,合并文件 +// if (new File(finalVideoPath).exists()) { +// List spliteFileList = new ArrayList<>(); +// spliteFileList.add(finalVideoPath); +// spliteFileList.add(currentFile.getAbsolutePath()); +// try { +// AWMp4ParserHelper.getInstance().mergeVideos(spliteFileList, tmpFile.getAbsolutePath()); +// if (tmpFile.exists()) { +// File finalVideoFile = new File(finalVideoPath); +// finalVideoFile.delete(); +// currentFile.delete(); +// tmpFile.renameTo(finalVideoFile); +// } else { +// Toast.makeText(PictureActivity.this, "视频合并失败!", Toast.LENGTH_SHORT).show(); +// } +// } catch (Exception e) { +// Log.e("PictureActivity", e.getMessage()); +// } +// } else { +// currentFile.renameTo(new File(finalVideoPath)); +// } +// } +// } +// runOnUiThread(new Runnable() { +// @Override +// public void run() { +// dismissLoadingDialog(); +// if (isFinishActivity) { +// PictureActivity.this.finish(); +// } +// } +// }); +// } +// }).start(); } @Override @@ -285,16 +290,17 @@ public class PictureActivity extends BaseActivity implements View.OnClickListene /** * 获取当前视频的时间,记录csv文件时使用 * */ - long currentTime = AWMp4ParserHelper.getInstance().getVedioTotalTime(new File(finalVideoPath)); +// long currentTime = AWMp4ParserHelper.getInstance().getVedioTotalTime(new File(finalVideoPath)); timerTask = new CsvTimerTask(new File(finalVideoPath+".txt")); + timer.schedule(timerTask, 0, period*1000); - // 开始采集,每隔2秒实时记录位置信息、视频时间以及设备时间 - if (currentTime == 0) { - timer.schedule(timerTask, 0, period*1000); - } else { - timerTask.setCurrentVideoTime(currentTime/1000+1); - timer.schedule(timerTask, 1, period*1000); - } +// // 开始采集,每隔2秒实时记录位置信息、视频时间以及设备时间 +// if (currentTime == 0) { +// timer.schedule(timerTask, 0, period*1000); +// } else { +// timerTask.setCurrentVideoTime(currentTime/1000+1); +// timer.schedule(timerTask, 1, period*1000); +// } } @@ -355,37 +361,43 @@ public class PictureActivity extends BaseActivity implements View.OnClickListene // startTakenVideo(); // 开始拍摄视频 // break; case R.id.btn_stop_video: - if (timerTask!=null){ - timerTask.cancel(); - Intent intent = new Intent(); - intent.putExtra(Constant.INTENT_VIDEO_PATH, finalVideoPath); - setResult(0x101, intent); - }else { - Toast.makeText(this, "本段视频没有计时!", Toast.LENGTH_SHORT).show(); - } - if (camera.isTakingVideo()) { - isFinishActivity = true; - camera.stopVideo(); - } else { - finish(); - } + stopVideoAndFinish(); break; } } + public void stopVideoAndFinish() { + showLoadingDialog(); + if (timerTask!=null){ + timerTask.cancel(); + Intent intent = new Intent(); + intent.putExtra(Constant.INTENT_VIDEO_PATH, finalVideoPath); + setResult(0x101, intent); + }else { + Toast.makeText(this, "本段视频没有计时!", Toast.LENGTH_SHORT).show(); + } + if (camera.isTakingVideo()) { + isFinishActivity = true; + camera.stopVideo(); + } else { + finish(); + } + } + private void startTakenVideo() { if (camera.isTakingVideo()) { Toast.makeText(this, "已经在拍摄中...", Toast.LENGTH_SHORT).show(); return; } - DateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss"); - Calendar calendar = Calendar.getInstance(); - calendar.setTimeInMillis(System.currentTimeMillis()); - String formatVideoName = formatter.format(calendar.getTime()); +// DateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss"); +// Calendar calendar = Calendar.getInstance(); +// calendar.setTimeInMillis(System.currentTimeMillis()); +// String formatVideoName = formatter.format(calendar.getTime()); //文件 - File file = new File(Constant.PICTURE_FOLDER, formatVideoName + ".mp4"); +// String path = finalVideoPath.substring(finalVideoPath.length()-20); + File file = new File(finalVideoPath); if (file.exists()) { try { FileOutputStream fo = new FileOutputStream(file); @@ -544,6 +556,12 @@ public class PictureActivity extends BaseActivity implements View.OnClickListene sb.append(Constant.currentLocation.getLatitude()); sb.append(","); sb.append(Constant.currentLocation.getLongitude()); + sb.append(","); + if (Constant.currentLocation.getBearing()!=0) { + sb.append(Constant.currentLocation.getBearing()); + } else { + sb.append(Constant.currentLocation.getDirection()); + } sb.append("\r\n"); FileUtils.writeFile(csvFile.getAbsolutePath(), sb.toString(), true); currentVideoTime = currentVideoTime+period; // diff --git a/app/src/main/java/com/navinfo/outdoor/fragment/RoadFragment.java b/app/src/main/java/com/navinfo/outdoor/fragment/RoadFragment.java index 4c298a6..2018613 100644 --- a/app/src/main/java/com/navinfo/outdoor/fragment/RoadFragment.java +++ b/app/src/main/java/com/navinfo/outdoor/fragment/RoadFragment.java @@ -27,6 +27,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.github.lazylibrary.util.FileUtils; +import com.github.lazylibrary.util.StringUtils; import com.github.lazylibrary.util.ZipUtil; import com.google.gson.Gson; import com.hjq.permissions.OnPermissionCallback; @@ -85,7 +86,6 @@ public class RoadFragment extends BaseDrawerFragment implements View.OnClickList private PoiDao poiDao; private PoiEntity showPoiEntity; private Button roadUpload; - private String videoPath; private File fileZip; private FrameLayout fmRoadPic; @@ -158,13 +158,14 @@ public class RoadFragment extends BaseDrawerFragment implements View.OnClickList fmRoadPic.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - if (v.getTag() == null) { + if (v.getTag() == null || ((List)v.getTag()).size()==0) { Toast.makeText(getActivity(), "还没有拍摄视频!", Toast.LENGTH_SHORT).show(); return; } - File videoFile = (File) v.getTag(); + + File finalFile = AWMp4ParserHelper.getInstance().obtainMp4FilePath(showPoiEntity.getId(), fmRoadPic.getTag()); Intent intent = new Intent(getContext(), PictureActivity.class); - intent.putExtra(Constant.INTENT_VIDEO_PATH, videoFile.getAbsolutePath()); + intent.putExtra(Constant.INTENT_VIDEO_PATH, finalFile.getAbsolutePath()); startActivityForResult(intent, 0x101); } }); @@ -189,13 +190,26 @@ public class RoadFragment extends BaseDrawerFragment implements View.OnClickList if (describe != null && !describe.equals("")) { etDesc.setText(describe); } - String photo = showPoiEntity.getPhoto(); - if (photo != null) { - File videoFile = new File(photo); - if (videoFile.exists()) { - // 使用glide加载视频的第一帧 - AWMp4ParserHelper.getInstance().loadFirstWithGlide(getActivity(), Uri.fromFile(videoFile).toString(), ivRoadPicture, 500); - fmRoadPic.setTag(videoFile); + String photoList = showPoiEntity.getPhoto(); + if (!StringUtils.isEmpty(photoList)) { + String[] photos = photoList.split(","); + List videoFileList = new ArrayList<>(); + boolean isImageLoad = false; + if (photos!=null&&photos.length>0) { + for (int i = 0; i < photos.length; i++) { + String photo = photos[i]; + if (!StringUtils.isEmpty(photo)) { + File videoFile = new File(photo); + videoFileList.add(new File(photo)); + if (videoFile.exists()&&!isImageLoad) { + // 使用glide加载视频的第一帧 + AWMp4ParserHelper.getInstance().loadFirstWithGlide(getActivity(), Uri.fromFile(videoFile).toString(), ivRoadPicture, 500); + isImageLoad = true; + } + } + } + + fmRoadPic.setTag(videoFileList); } } } @@ -257,27 +271,29 @@ public class RoadFragment extends BaseDrawerFragment implements View.OnClickList case R.id.tv_pictures: // 根据用户点击的时间为视频名称赋值 - DateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss"); - String videoFormatName = formatter.format(new Date()); +// DateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss"); +// String videoFormatName = formatter.format(new Date()); Intent intent = new Intent(getContext(), PictureActivity.class); - intent.putExtra(Constant.INTENT_VIDEO_PATH, Constant.PICTURE_FOLDER + "/" + videoFormatName + ".mp4"); + File finalFile = AWMp4ParserHelper.getInstance().obtainMp4FilePath(showPoiEntity.getId(), fmRoadPic.getTag()); + intent.putExtra(Constant.INTENT_VIDEO_PATH, finalFile.getAbsolutePath()); startActivityForResult(intent, 0x101); break; case R.id.road_upload: showLoadingDialog(); - ArrayList videoFileList = new ArrayList<>(); + ArrayList fileList = new ArrayList<>(); if (fmRoadPic.getTag() != null) { - - File videoFile = (File) fmRoadPic.getTag(); - videoFileList.add(videoFile); - File file = new File(videoFile.getPath() + ".txt"); - videoFileList.add(file); + List videoFileList = (List) fmRoadPic.getTag(); + for (File videoFile: videoFileList) { + fileList.add(videoFile); + File file = new File(videoFile.getPath() + ".txt"); + fileList.add(file); + } fileZip = new File(Constant.PICTURE_FOLDER, "files" + ".zip"); new Thread(new Runnable() { @Override public void run() { - ZipUtil.zipFiles(videoFileList, fileZip, null); + ZipUtil.zipFiles(fileList, fileZip, null); PoiEntity poiDaoPoiEntity = poiDao.getPoiEntity(showPoiEntity.getId()); if (poiDaoPoiEntity == null || poiDaoPoiEntity.getTaskStatus() == 1 || poiDaoPoiEntity.getTaskStatus() == 2 || poiDaoPoiEntity.getTaskStatus() == 0) { dismissLoadingDialog(); @@ -349,29 +365,18 @@ public class RoadFragment extends BaseDrawerFragment implements View.OnClickList poiEntity.setTaskId(showPoiEntity.getTaskId()); } } - if (fmRoadPic.getTag() == null) { + if (fmRoadPic.getTag() == null||((List) fmRoadPic.getTag()).isEmpty()) { Toast.makeText(getActivity(), "请录像", Toast.LENGTH_SHORT).show(); return; } else { - File videoFile = (File) fmRoadPic.getTag(); - String path = videoFile.getPath() + ".txt"; - poiEntity.setPhoto(videoFile.getAbsolutePath()); - List strings = FileUtils.readFileToList(path, "utf-8"); - ArrayList latLngs = new ArrayList<>(); - for (int i = 0; i < strings.size(); i++) { - String[] split = strings.get(i).split(","); - LatLng latLng = new LatLng(); - latLng.setLatitude(Double.valueOf(split[2])); - latLng.setLongitude(Double.valueOf(split[3])); - latLngs.add(latLng); - } - if (strings.size() == 1) { - LatLng latLng = latLngs.get(0); - latLngs.add(latLng); - } - String lineString = GeometryTools.getLineString(latLngs); + + String lineString = GeometryTools.getLineString(getLineString()); + String filePathString = getPhotoStrFromTag(); Log.d("TAG", "onGranted: " + lineString); - poiEntity.setGeoWkt(lineString); + poiEntity.setPhoto(filePathString); + if (lineString!=null) { + poiEntity.setGeoWkt(lineString); + } } int pictureType = getPictureType(); if (pictureType == -1) { @@ -418,6 +423,45 @@ public class RoadFragment extends BaseDrawerFragment implements View.OnClickList }); } + private String getPhotoStrFromTag() { + List videoFileList = (List) fmRoadPic.getTag(); + + StringBuilder filePathStringBuilder = new StringBuilder(""); + for (int m = 0; m < videoFileList.size(); m++) { + File videoFile = videoFileList.get(m); + filePathStringBuilder.append(videoFile.getAbsolutePath()); + if (m != videoFileList.size()-1) { + filePathStringBuilder.append(","); + } + } + return filePathStringBuilder.toString(); + } + + private List getLineString() { + List videoFileList = (List) fmRoadPic.getTag(); + + List latLngs = new ArrayList<>(); + StringBuilder filePathStringBuilder = new StringBuilder(""); + for (int m = 0; m < videoFileList.size(); m++) { + File videoFile = videoFileList.get(m); + + String path = videoFile.getPath() + ".txt"; + List strings = FileUtils.readFileToList(path, "utf-8"); + for (int i = 0; i < strings.size(); i++) { + String[] split = strings.get(i).split(","); + LatLng latLng = new LatLng(); + latLng.setLatitude(Double.valueOf(split[2])); + latLng.setLongitude(Double.valueOf(split[3])); + latLngs.add(latLng); + } + if (strings.size() == 1) { + LatLng latLng = latLngs.get(0); + latLngs.add(latLng); + } + } + return latLngs; + } + private void poiVideoUpload(int body, File fileZip) { if (body == 0) { Toast.makeText(getContext(), "请先保存本地在上传", Toast.LENGTH_SHORT).show(); @@ -534,11 +578,15 @@ public class RoadFragment extends BaseDrawerFragment implements View.OnClickList if (requestCode == 0x101) { if (resultCode == 0x101) { if (data != null && data.hasExtra(Constant.INTENT_VIDEO_PATH)) { - videoPath = data.getStringExtra(Constant.INTENT_VIDEO_PATH); + String videoPath = data.getStringExtra(Constant.INTENT_VIDEO_PATH); File videoFile = new File(videoPath); if (videoFile.exists()) { AWMp4ParserHelper.getInstance().loadFirstWithGlide(getActivity(), Uri.fromFile(videoFile).toString(), ivRoadPicture, 500); - fmRoadPic.setTag(videoFile); + if (fmRoadPic.getTag() == null) { + fmRoadPic.setTag(new ArrayList<>()); + } + List fileList = (List) fmRoadPic.getTag(); + fileList.add(videoFile); } } } @@ -590,6 +638,7 @@ public class RoadFragment extends BaseDrawerFragment implements View.OnClickList poiEntity.setType(4); poiEntity.setTaskStatus(2); poiEntity.setIsLocalData(1); + poiEntity.setPhoto(getPhotoStrFromTag()); String newPoiEntity = new Gson().toJson(poiEntity); //以键值对的形式添加新值。 edit.putString("poiEntity", newPoiEntity); diff --git a/app/src/main/java/com/navinfo/outdoor/util/AWMp4ParserHelper.java b/app/src/main/java/com/navinfo/outdoor/util/AWMp4ParserHelper.java index 5ec4ce5..3ad60ad 100644 --- a/app/src/main/java/com/navinfo/outdoor/util/AWMp4ParserHelper.java +++ b/app/src/main/java/com/navinfo/outdoor/util/AWMp4ParserHelper.java @@ -14,17 +14,20 @@ import com.bumptech.glide.load.resource.bitmap.BitmapTransformation; import com.bumptech.glide.load.resource.bitmap.VideoDecoder; import com.bumptech.glide.request.RequestOptions; import com.coremedia.iso.boxes.Container; +import com.github.lazylibrary.util.StringUtils; import com.googlecode.mp4parser.authoring.Movie; import com.googlecode.mp4parser.authoring.Track; import com.googlecode.mp4parser.authoring.builder.DefaultMp4Builder; import com.googlecode.mp4parser.authoring.container.mp4.MovieCreator; import com.googlecode.mp4parser.authoring.tracks.AppendTrack; +import com.navinfo.outdoor.api.Constant; import java.io.File; import java.io.IOException; import java.io.RandomAccessFile; import java.nio.channels.FileChannel; import java.security.MessageDigest; +import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedList; @@ -38,10 +41,12 @@ import java.util.Map; */ public class AWMp4ParserHelper { private static AWMp4ParserHelper instance; + private static SimpleDateFormat simpleDateFormat; public static AWMp4ParserHelper getInstance() { if (instance == null) { instance = new AWMp4ParserHelper(); + simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss"); } return instance; } @@ -182,4 +187,31 @@ public class AWMp4ParserHelper { } return bitmap; } + + /** + * 生成mp4文件拍摄的生成路径 + * */ + public File obtainMp4FilePath(String uuid, Object tag) { + if (tag == null) { + return new File(Constant.PICTURE_FOLDER+"/"+uuid+"-0.mp4"); + } + List fileList = (List) tag; + if (fileList == null || fileList.isEmpty()) { + return new File(Constant.PICTURE_FOLDER+"/"+uuid+"-0.mp4"); + } + int maxIndex = 0; + for (int i = 0; i < fileList.size(); i++) { + File file = fileList.get(i); + if (file!=null) { + String[] fileSplite = file.getName().replace(".mp4", "").split("-"); + if (fileSplite!=null&&fileSplite.length>0&&fileSplite[fileSplite.length-1]!=null) { + int index = Integer.parseInt(fileSplite[fileSplite.length-1]); + if (index>=maxIndex) { + maxIndex = index; + } + } + } + } + return new File(Constant.PICTURE_FOLDER+"/"+uuid+"-"+(maxIndex+1)+".mp4"); + } } diff --git a/app/src/main/res/layout/activity_picture.xml b/app/src/main/res/layout/activity_picture.xml index 65b3d33..2351b5c 100644 --- a/app/src/main/res/layout/activity_picture.xml +++ b/app/src/main/res/layout/activity_picture.xml @@ -72,6 +72,7 @@ android:layout_height="wrap_content" android:background="@drawable/uploding_shape" android:text="结束采集" + android:visibility="gone" android:textColor="@color/colorBlue" app:layout_constraintBottom_toBottomOf="@id/capuretVideo" app:layout_constraintLeft_toRightOf="@id/capuretVideo"