Related
Here is my logcat:
System.err:java.lang.IllegalStateException: Failed to add the track to the muxer
W/System.err: at android.media.MediaMuxer.nativeAddTrack(Native Method)
W/System.err: at android.media.MediaMuxer.addTrack(MediaMuxer.java:626)
W/System.err: at com.marvhong.videoeffect.composer.MuxRender.onSetOutputFormat(MuxRender.java:64)
W/System.err: at com.marvhong.videoeffect.composer.VideoComposer.drainEncoder(VideoComposer.java:224)
W/System.err: at com.marvhong.videoeffect.composer.VideoComposer.stepPipeline(VideoComposer.java:113)
W/System.err: at com.marvhong.videoeffect.composer.Mp4ComposerEngine.runPipelines(Mp4ComposerEngine.java:181)
W/System.err: at com.marvhong.videoeffect.composer.Mp4ComposerEngine.compose(Mp4ComposerEngine.java:127)
W/System.err: at com.marvhong.videoeffect.composer.Mp4Composer$1.run(Mp4Composer.java:198)
W/System.err: at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
W/System.err: at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
W/System.err: at java.lang.Thread.run(Thread.java:764)
E/TrimVideoActivity: filterVideo---onFailed()
In my application, I'm trying to add filters on video. But sometimes my app crashes and sometimes it works fine. The error is Failed to add the track to the muxer
I have debugged code and found the issue for video under audio available then apply filter and save it but doesn't work save filter video.
MuxRender Class :
class MuxRender {
private static final String TAG = "MuxRender";
private static final int BUFFER_SIZE = 64 * 1024; // I have no idea whether this value is appropriate or not...
private final MediaMuxer muxer;
private MediaFormat videoFormat;
private MediaFormat audioFormat;
private int videoTrackIndex;
private int audioTrackIndex;
private ByteBuffer byteBuffer;
private final List<SampleInfo> sampleInfoList;
private boolean started;
MuxRender(MediaMuxer muxer) {
this.muxer = muxer;
sampleInfoList = new ArrayList<>();
}
void setOutputFormat(SampleType sampleType, MediaFormat format) {
switch (sampleType) {
case VIDEO:
videoFormat = format;
break;
case AUDIO:
ObLogger.i(TAG, "format > " + format);
audioFormat = format;
break;
default:
throw new AssertionError();
}
}
void onSetOutputFormat() {
if (videoFormat != null && audioFormat != null) {
videoTrackIndex = muxer.addTrack(videoFormat);
ObLogger.v(TAG, "Added track #" + videoTrackIndex + " with " + videoFormat.getString(
MediaFormat.KEY_MIME) + " to muxer");
ObLogger.i(TAG, "audioFormat > " + audioFormat);
audioTrackIndex = muxer.addTrack(audioFormat);
ObLogger.v(TAG, "Added track #" + audioTrackIndex + " with " + audioFormat.getString(
MediaFormat.KEY_MIME) + " to muxer");
} else if (videoFormat != null) {
videoTrackIndex = muxer.addTrack(videoFormat);
ObLogger.v(TAG, "Added track #" + videoTrackIndex + " with " + videoFormat.getString(
MediaFormat.KEY_MIME) + " to muxer");
}
muxer.start();
started = true;
if (byteBuffer == null) {
byteBuffer = ByteBuffer.allocate(0);
}
byteBuffer.flip();
ObLogger.v(TAG, "Output format determined, writing " + sampleInfoList.size() +
" samples / " + byteBuffer.limit() + " bytes to muxer.");
MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();
int offset = 0;
for (SampleInfo sampleInfo : sampleInfoList) {
sampleInfo.writeToBufferInfo(bufferInfo, offset);
muxer.writeSampleData(getTrackIndexForSampleType(sampleInfo.sampleType), byteBuffer, bufferInfo);
offset += sampleInfo.size;
}
sampleInfoList.clear();
byteBuffer = null;
}
void writeSampleData(SampleType sampleType, ByteBuffer byteBuf, MediaCodec.BufferInfo bufferInfo) {
if (started) {
muxer.writeSampleData(getTrackIndexForSampleType(sampleType), byteBuf, bufferInfo);
return;
}
byteBuf.limit(bufferInfo.offset + bufferInfo.size);
byteBuf.position(bufferInfo.offset);
if (byteBuffer == null) {
byteBuffer = ByteBuffer.allocateDirect(BUFFER_SIZE).order(ByteOrder.nativeOrder());
}
byteBuffer.put(byteBuf);
sampleInfoList.add(new SampleInfo(sampleType, bufferInfo.size, bufferInfo));
}
private int getTrackIndexForSampleType(SampleType sampleType) {
switch (sampleType) {
case VIDEO:
return videoTrackIndex;
case AUDIO:
return audioTrackIndex;
default:
throw new AssertionError();
}
}
public enum SampleType {VIDEO, AUDIO}
private static class SampleInfo {
private final SampleType sampleType;
private final int size;
private final long presentationTimeUs;
private final int flags;
private SampleInfo(SampleType sampleType, int size, MediaCodec.BufferInfo bufferInfo) {
this.sampleType = sampleType;
this.size = size;
presentationTimeUs = bufferInfo.presentationTimeUs;
flags = bufferInfo.flags;
}
private void writeToBufferInfo(MediaCodec.BufferInfo bufferInfo, int offset) {
bufferInfo.set(offset, size, presentationTimeUs, flags);
}
}
}
Mp4ComposerEngine Class:
class Mp4ComposerEngine {
private static final String TAG = "Mp4ComposerEngine";
private static final double PROGRESS_UNKNOWN = -1.0;
private static final long SLEEP_TO_WAIT_TRACK_TRANSCODERS = 10;
private static final long PROGRESS_INTERVAL_STEPS = 10;
private FileDescriptor inputFileDescriptor;
private VideoComposer videoComposer;
private IAudioComposer audioComposer;
private MediaExtractor mediaExtractor;
private MediaMuxer mediaMuxer;
private ProgressCallback progressCallback;
private long durationUs;
void setDataSource(FileDescriptor fileDescriptor) {
inputFileDescriptor = fileDescriptor;
}
void setProgressCallback(ProgressCallback progressCallback) {
this.progressCallback = progressCallback;
}
void compose(
final String destPath,
final Resolution outputResolution,
final GlFilter filter,
final int bitrate,
final boolean mute,
final Rotation rotation,
final Resolution inputResolution,
final FillMode fillMode,
final FillModeCustomItem fillModeCustomItem,
final int timeScale,
final boolean flipVertical,
final boolean flipHorizontal
) throws IOException {
try {
mediaExtractor = new MediaExtractor();
mediaExtractor.setDataSource(inputFileDescriptor);
if (VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN_MR2) {
mediaMuxer = new MediaMuxer(destPath, OutputFormat.MUXER_OUTPUT_MPEG_4);
}
MediaMetadataRetriever mediaMetadataRetriever = new MediaMetadataRetriever();
mediaMetadataRetriever.setDataSource(inputFileDescriptor);
try {
durationUs = Long
.parseLong(mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION)) * 1000;
} catch (NumberFormatException e) {
durationUs = -1;
}
ObLogger.d(TAG, "Duration (us): " + durationUs);
MediaFormat videoOutputFormat = MediaFormat
.createVideoFormat("video/avc", outputResolution.width(), outputResolution.height());
videoOutputFormat.setInteger(MediaFormat.KEY_BIT_RATE, bitrate);
videoOutputFormat.setInteger(MediaFormat.KEY_FRAME_RATE, 30);
videoOutputFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 1);
videoOutputFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, CodecCapabilities.COLOR_FormatSurface);
MuxRender muxRender = new MuxRender(mediaMuxer);
// identify track indices
MediaFormat format = mediaExtractor.getTrackFormat(0);
String mime = format.getString(MediaFormat.KEY_MIME);
final int videoTrackIndex;
final int audioTrackIndex;
if (mime.startsWith("video/")) {
videoTrackIndex = 0;
audioTrackIndex = 1;
} else {
videoTrackIndex = 1;
audioTrackIndex = 0;
}
// setup video composer
videoComposer = new VideoComposer(mediaExtractor, videoTrackIndex, videoOutputFormat, muxRender, timeScale);
videoComposer.setUp(filter, rotation, outputResolution, inputResolution, fillMode, fillModeCustomItem, flipVertical, flipHorizontal);
mediaExtractor.selectTrack(videoTrackIndex);
// setup audio if present and not muted
if (mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_HAS_AUDIO) != null && !mute) {
// has Audio video
if (timeScale < 2) {
audioComposer = new AudioComposer(mediaExtractor, audioTrackIndex, muxRender);
} else {
audioComposer = new RemixAudioComposer(mediaExtractor, audioTrackIndex, mediaExtractor.getTrackFormat(audioTrackIndex), muxRender, timeScale);
}
audioComposer.setup();
mediaExtractor.selectTrack(audioTrackIndex);
runPipelines();
} else {
// no audio video
runPipelinesNoAudio();
}
if (VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN_MR2) {
mediaMuxer.stop();
}
} finally {
try {
if (videoComposer != null) {
videoComposer.release();
videoComposer = null;
}
if (audioComposer != null) {
audioComposer.release();
audioComposer = null;
}
if (mediaExtractor != null) {
mediaExtractor.release();
mediaExtractor = null;
}
} catch (RuntimeException e) {
e.printStackTrace();
// Too fatal to make alive the app, because it may leak native resources.
// throw new Error("Could not shutdown mediaExtractor, codecs and mediaMuxer pipeline.", e);
}
try {
if (mediaMuxer != null) {
if (VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN_MR2) {
mediaMuxer.release();
}
mediaMuxer = null;
}
} catch (RuntimeException e) {
ObLogger.e(TAG, "Failed to release mediaMuxer.", e);
}
}
}
private void runPipelines() {
long loopCount = 0;
if (durationUs <= 0) {
if (progressCallback != null) {
progressCallback.onProgress(PROGRESS_UNKNOWN);
}// unknown
}
while (!(videoComposer.isFinished() && audioComposer.isFinished())) {
boolean stepped = videoComposer.stepPipeline()
|| audioComposer.stepPipeline();
loopCount++;
if (durationUs > 0 && loopCount % PROGRESS_INTERVAL_STEPS == 0) {
double videoProgress = videoComposer.isFinished() ? 1.0 : Math
.min(1.0, (double) videoComposer.getWrittenPresentationTimeUs() / durationUs);
double audioProgress = audioComposer.isFinished() ? 1.0 : Math
.min(1.0, (double) audioComposer.getWrittenPresentationTimeUs() / durationUs);
double progress = (videoProgress + audioProgress) / 2.0;
if (progressCallback != null) {
progressCallback.onProgress(progress);
}
}
if (!stepped) {
try {
Thread.sleep(SLEEP_TO_WAIT_TRACK_TRANSCODERS);
} catch (InterruptedException e) {
// nothing to do
}
}
}
}
private void runPipelinesNoAudio() {
long loopCount = 0;
if (durationUs <= 0) {
if (progressCallback != null) {
progressCallback.onProgress(PROGRESS_UNKNOWN);
} // unknown
}
while (!videoComposer.isFinished()) {
boolean stepped = videoComposer.stepPipeline();
loopCount++;
if (durationUs > 0 && loopCount % PROGRESS_INTERVAL_STEPS == 0) {
double videoProgress = videoComposer.isFinished() ? 1.0 : Math
.min(1.0, (double) videoComposer.getWrittenPresentationTimeUs() / durationUs);
if (progressCallback != null) {
progressCallback.onProgress(videoProgress);
}
}
if (!stepped) {
try {
Thread.sleep(SLEEP_TO_WAIT_TRACK_TRANSCODERS);
} catch (InterruptedException e) {
// nothing to do
}
}
}
}
interface ProgressCallback {
/**
* Called to notify progress. Same thread which initiated transcode is used.
*
* #param progress Progress in [0.0, 1.0] range, or negative value if progress is unknown.
*/
void onProgress(double progress);
}
}
Mp4Composer Class :
public class Mp4Composer {
private final static String TAG = Mp4Composer.class.getSimpleName();
private final String srcPath;
private final String destPath;
private GlFilter filter;
private Resolution outputResolution;
private int bitrate = -1;
private boolean mute = false;
private Rotation rotation = Rotation.NORMAL;
private Listener listener;
private FillMode fillMode = FillMode.PRESERVE_ASPECT_FIT;
private FillModeCustomItem fillModeCustomItem;
private int timeScale = 1;
private boolean flipVertical = false;
private boolean flipHorizontal = false;
private ExecutorService executorService;
public Mp4Composer(#NonNull final String srcPath, #NonNull final String destPath) {
this.srcPath = srcPath;
this.destPath = destPath;
}
public Mp4Composer filter(#NonNull GlFilter filter) {
this.filter = filter;
return this;
}
public Mp4Composer size(int width, int height) {
this.outputResolution = new Resolution(width, height);
return this;
}
public Mp4Composer videoBitrate(int bitrate) {
this.bitrate = bitrate;
return this;
}
public Mp4Composer mute(boolean mute) {
this.mute = mute;
return this;
}
public Mp4Composer flipVertical(boolean flipVertical) {
this.flipVertical = flipVertical;
return this;
}
public Mp4Composer flipHorizontal(boolean flipHorizontal) {
this.flipHorizontal = flipHorizontal;
return this;
}
public Mp4Composer rotation(#NonNull Rotation rotation) {
this.rotation = rotation;
return this;
}
public Mp4Composer fillMode(#NonNull FillMode fillMode) {
this.fillMode = fillMode;
return this;
}
public Mp4Composer customFillMode(#NonNull FillModeCustomItem fillModeCustomItem) {
this.fillModeCustomItem = fillModeCustomItem;
this.fillMode = FillMode.CUSTOM;
return this;
}
public Mp4Composer listener(#NonNull Listener listener) {
this.listener = listener;
return this;
}
public Mp4Composer timeScale(final int timeScale) {
this.timeScale = timeScale;
return this;
}
private ExecutorService getExecutorService() {
if (executorService == null) {
executorService = Executors.newSingleThreadExecutor();
}
return executorService;
}
public Mp4Composer start() {
getExecutorService().execute(new Runnable() {
#Override
public void run() {
Mp4ComposerEngine engine = new Mp4ComposerEngine();
engine.setProgressCallback(new Mp4ComposerEngine.ProgressCallback() {
#Override
public void onProgress(final double progress) {
if (listener != null) {
listener.onProgress(progress);
}
}
});
final File srcFile = new File(srcPath);
final FileInputStream fileInputStream;
try {
fileInputStream = new FileInputStream(srcFile);
} catch (FileNotFoundException e) {
e.printStackTrace();
if (listener != null) {
listener.onFailed(e);
}
return;
}
try {
engine.setDataSource(fileInputStream.getFD());
} catch (IOException e) {
e.printStackTrace();
if (listener != null) {
listener.onFailed(e);
}
return;
}
final int videoRotate = getVideoRotation(srcPath);
final Resolution srcVideoResolution = getVideoResolution(srcPath, videoRotate);
if (filter == null) {
filter = new GlFilter();
}
if (fillMode == null) {
fillMode = FillMode.PRESERVE_ASPECT_FIT;
}
if (fillModeCustomItem != null) {
fillMode = FillMode.CUSTOM;
}
if (outputResolution == null) {
if (fillMode == FillMode.CUSTOM) {
outputResolution = srcVideoResolution;
} else {
Rotation rotate = Rotation.fromInt(rotation.getRotation() + videoRotate);
if (rotate == Rotation.ROTATION_90 || rotate == Rotation.ROTATION_270) {
outputResolution = new Resolution(srcVideoResolution.height(), srcVideoResolution.width());
} else {
outputResolution = srcVideoResolution;
}
}
}
if (filter instanceof IResolutionFilter) {
((IResolutionFilter) filter).setResolution(outputResolution);
}
if (timeScale < 2) {
timeScale = 1;
}
ObLogger.d(TAG, "rotation = " + (rotation.getRotation() + videoRotate));
ObLogger.d(TAG, "inputResolution width = " + srcVideoResolution.width() + " height = " + srcVideoResolution.height());
ObLogger.d(TAG, "outputResolution width = " + outputResolution.width() + " height = " + outputResolution.height());
ObLogger.d(TAG, "fillMode = " + fillMode);
try {
if (bitrate < 0) {
bitrate = calcBitRate(outputResolution.width(), outputResolution.height());
}
engine.compose(
destPath,
outputResolution,
filter,
bitrate,
mute,
Rotation.fromInt(rotation.getRotation() + videoRotate),
srcVideoResolution,
fillMode,
fillModeCustomItem,
timeScale,
flipVertical,
flipHorizontal
);
} catch (Exception e) {
e.printStackTrace();
if (listener != null) {
listener.onFailed(e);
}
executorService.shutdown();
return;
}
if (listener != null) {
listener.onCompleted();
}
executorService.shutdown();
}
});
return this;
}
public void cancel() {
getExecutorService().shutdownNow();
}
public interface Listener {
/**
* Called to notify progress.
*
* #param progress Progress in [0.0, 1.0] range, or negative value if progress is unknown.
*/
void onProgress(double progress);
/**
* Called when transcode completed.
*/
void onCompleted();
/**
* Called when transcode canceled.
*/
void onCanceled();
void onFailed(Exception exception);
}
private int getVideoRotation(String videoFilePath) {
try {
MediaMetadataRetriever mediaMetadataRetriever = new MediaMetadataRetriever();
mediaMetadataRetriever.setDataSource(videoFilePath);
ObLogger.e("MediaMetadataRetriever", "getVideoRotation error");
String orientation = mediaMetadataRetriever.extractMetadata(
MediaMetadataRetriever.METADATA_KEY_VIDEO_ROTATION);
return Integer.valueOf(orientation);
} catch (NumberFormatException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
}
return 0;
}
private int calcBitRate(int width, int height) {
final int bitrate = (int) (0.25 * 30 * width * height);
ObLogger.i(TAG, "bitrate=" + bitrate);
return bitrate;
}
private Resolution getVideoResolution(final String path, final int rotation) {
int width = 0;
int height = 0;
if (path != null && !path.isEmpty()) {
MediaMetadataRetriever retriever = new MediaMetadataRetriever();
retriever.setDataSource(path);
try {
String Strwidth = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH);
String Strheight = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT);
if (Strwidth != null && Strheight != null) {
width = Integer.valueOf(Strwidth);
height = Integer.valueOf(Strheight);
}
retriever.release();
} catch (NumberFormatException e) {
retriever.release();
e.printStackTrace();
} catch (IllegalArgumentException e) {
retriever.release();
e.printStackTrace();
}
}
return new Resolution(width, height);
}
}
Main Activity Call Mp4Composer:
private void startMediaCodec(String srcPath,String outputPath) {
mMp4Composer = new Mp4Composer(srcPath, outputPath)
// .rotation(Rotation.ROTATION_270)
//.size(720, 1280)
.fillMode(FillMode.PRESERVE_ASPECT_FIT)
.filter(MagicFilterFactory.getFilter())
.mute(false)
.flipHorizontal(false)
.flipVertical(false)
.listener(new Listener() {
#Override
public void onProgress(double progress) {
ObLogger.d(TAG, "filterVideo---onProgress: " + (int) (progress * 100));
runOnUiThread(new Runnable() {
#Override
public void run() {
//show progress
}
});
}
#Override
public void onCompleted() {
ObLogger.d(TAG, "filterVideo---onCompleted");
runOnUiThread(new Runnable() {
#Override
public void run() {
ObLogger.i(TAG, "run: Editor Screen is >>> ");
Intent intent = new Intent();
intent.putExtra(Extras.EXTRA_FILTER_SCREEN, outputPath);
setResult(RESULT_OK, intent);
finish();
}
});
}
#Override
public void onCanceled() {
ObLogger.e(TAG, "onCanceled");
NormalProgressDialog.stopLoading();
}
#Override
public void onFailed(Exception exception) {
ObLogger.e(TAG, "filterVideo---onFailed()");
NormalProgressDialog.stopLoading();
// Toast.makeText(TrimVideoActivity.this, "Video processing failed", Toast.LENGTH_SHORT).show();
}
})
.start();
}
The below links were used but my problem is not solved.
https://stackoverflow.com/a/53140941/11138845
https://stackoverflow.com/a/21759073/11138845
In CameraX Analysis, setTargetResolution(new Size(2560, 800), but in Analyzer imageProxy.getImage.getWidth=1280 and getHeight=400, and YUVToByte(imageProxy.getImage).length()=768000。In Camera, parameter.setPreviewSize(2560, 800) then byte[].length in onPreviewFrame is 3072000(equales 768000*(2560/1280)*(800/400))。How can I make CameraX Analyzer imageProxy.getImage.getWidth and getHeight = 2560 and 800, and YUVToByte(ImageProxy.getImage).length()=3072000? In CameraX onPreviewFrame(), res always = null, in Camera onPreviewFrame(), res can get currect value, what's the different between CameraX and Camera? And what should I do in CameraX?
CameraX:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
try {
copyDataBase();
} catch (IOException e) {
e.printStackTrace();
}
getSupportActionBar().hide();
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
viewFinder = findViewById(R.id.previewView);
executor = Executors.newSingleThreadExecutor();
if (!allPermissionGranted()) {
ActivityCompat.requestPermissions(this, REQUIRED_PERMISSIONS, REQUEST_CODE_PERMISSIONS);
}
DisplayMetrics metric = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metric);
width = metric.widthPixels;
height = metric.heightPixels;
l = 100;
r = width - 100;
ntmpH = (r - l) * 58 / 100;
t = (height - ntmpH) / 2;
b = t + ntmpH;
double proportion = (double) width / (double) preHeight;
double hproportion = (double) height / (double) preWidth;
l = (int) (l / proportion);
t = (int) (t / hproportion);
r = (int) (r / proportion);
b = (int) (b / hproportion);
m_ROI[0] = l;
m_ROI[1] = t;
m_ROI[2] = r;
m_ROI[3] = b;
cameraProviderFuture = processCameraProvider.getInstance(this);
cameraProviderFuture.addListener(() -> {
try {
ProcessCameraProvider cameraProvider = cameraProviderFuture.get();
#SuppressLint("RestrictedApi") Preview preview = new Preview.Builder().build();
CameraSelector cameraSelector = new CameraSelector.Builder().
requireLensFacing(CameraSelector.LENS_FACING_BACK).build();
ImageAnalysis imageAnalysis = new ImageAnalysis.Builder()
.setTargetResolution(new Size(2560, 800))
.setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
.setTargetRotation(Surface.ROTATION_90)
.build();
imageAnalysis.setAnalyzer(executor, new ImageAnalysis.Analyzer() {
#SuppressLint("UnsafeExperimentalUsageError")
#Override
public void analyze(#NonNull ImageProxy imageProxy) {
if (imageProxy.getFormat() == ImageFormat.YUV_420_888) {
image = imageProxy.getImage();
bIninKernal();
Log.d("Size ", image.getWidth() + "/" + image.getHeight());
onPreviewFrame(YUVToByte(image));
} else {
Log.d("Status ", "照片格式錯誤" + imageProxy.getFormat());
}
imageProxy.close();
}
});
cameraProvider.bindToLifecycle(this, cameraSelector, preview, imageAnalysis);
preview.setSurfaceProvider(viewFinder.createSurfaceProvider());
} catch (ExecutionException | InterruptedException e) {
e.printStackTrace();
}
}, ContextCompat.getMainExecutor(this));
}
#NonNull
#Override
public CameraXConfig getCameraXConfig() {
return Camera2Config.defaultConfig();
}
private boolean allPermissionGranted() {
for (String permission : REQUIRED_PERMISSIONS) {
if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) {
return false;
}
}
return true;
}
private byte[] YUVToByte(Image image) {
Image.Plane[] planes = image.getPlanes();
ByteBuffer buffer0 = planes[0].getBuffer();
ByteBuffer buffer1 = planes[1].getBuffer();
ByteBuffer buffer2 = planes[2].getBuffer();
int width = image.getWidth();
int height = image.getHeight();
byte[] data = new byte[image.getWidth() * image.getHeight() * ImageFormat.getBitsPerPixel(ImageFormat.YUV_420_888) / 8];
byte[] rowData1 = new byte[planes[1].getRowStride()];
byte[] rowData2 = new byte[planes[2].getRowStride()];
int bytesPerPixel = ImageFormat.getBitsPerPixel(ImageFormat.YUV_420_888) / 8;
// loop via rows of u/v channels
int offsetY = 0;
int sizeY = width * height * bytesPerPixel;
int sizeUV = (width * height * bytesPerPixel) / 4;
for (int row = 0; row < height; row++) {
// fill data for Y channel, two row
{
int length = bytesPerPixel * width;
buffer0.get(data, offsetY, length);
if (height - row != 1)
buffer0.position(buffer0.position() + planes[0].getRowStride() - length);
offsetY += length;
}
if (row >= height / 2)
continue;
{
int uvlength = planes[1].getRowStride();
if ((height / 2 - row) == 1) {
uvlength = width / 2 - planes[1].getPixelStride() + 1;
}
buffer1.get(rowData1, 0, uvlength);
buffer2.get(rowData2, 0, uvlength);
// fill data for u/v channels
for (int col = 0; col < width / 2; ++col) {
// u channel
data[sizeY + (row * width) / 2 + col] = rowData1[col * planes[1].getPixelStride()];
// v channel
data[sizeY + sizeUV + (row * width) / 2 + col] = rowData2[col * planes[2].getPixelStride()];
}
}
}
return data;
}
private void bIninKernal() {
api = new LPR();
String FilePath = Environment.getExternalStorageDirectory().toString() + "/lpr.key";
int nRet = api.Init(this, m_ROI[0], m_ROI[1], m_ROI[2], m_ROI[3], preHeight, preWidth, FilePath);
if (nRet != 0) {
bInitKernal = false;
Log.d("Status ", "相機開啟失敗");
} else {
bInitKernal = true;
}
}
private void onPreviewFrame(byte[] data) {
bIninKernal();
tackData = data;
Log.d("data length ", data.length + "");
resultStr = "";
if (!leaving && bInitKernal) {
byte[] result;
String res = "";
result = api.VideoRec(tackData, 1280, 400, 1);
try {
res = new String(result, "gb2312");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
if (res != null && !"".equals(res.trim())) {
resultStr = res.trim();
if (resultStr != "") {
leaving = true;
MediaActionSound sound = new MediaActionSound();
sound.play(MediaActionSound.SHUTTER_CLICK);
Log.d("Status ", "辨識成功");
Log.d("車牌號碼", resultStr);
Thread thread = new Thread(Image_update);
thread.start();
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
Intent intent = new Intent(MainActivity2.this, MainActivity.class);
intent.putExtra("result", resultStr);
Log.d("result", resultStr);
setResult(1, intent);
finish();
}
} else {
Log.d("Status ", "未分辨車牌號碼,請重拍");
}
}
}
public void copyDataBase() throws IOException {
// Common common = new Common();
// 取得SK卡路徑/lpr.key
String dst = Environment.getExternalStorageDirectory().toString() + "/lpr.key";
File file = new File(dst);
if (!file.exists()) {
// file.createNewFile();
} else {
file.delete();
}
Log.d("File Name", file.toString());
try {
InputStream myInput = getAssets().open("lpr.key");
OutputStream myOutput = new FileOutputStream(dst);
byte[] buffer = new byte[1024];
int length;
while ((length = myInput.read(buffer)) > 0) {
myOutput.write(buffer, 0, length);
}
myOutput.flush();
myOutput.close();
myInput.close();
} catch (Exception e) {
System.out.println("lpr.key" + "is not found");
}
}
private Runnable Image_update = new Runnable() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://0d9dccd7eac8.ngrok.io/")
.addConverterFactory(GsonConverterFactory.create())
.build();
MyAPIService myAPIService = retrofit.create(MyAPIService.class);
#Override
public void run() {
Log.d("Status ", "run");
Log.d("resultStr ", resultStr);
String url = "D:\\Images\\license_plate\\";
String imgStr = bitmap2base64(toBitmap(image));
LicensePlate licensePlate = new LicensePlate();
licensePlate.setsPlate(resultStr);
licensePlate.setsPicPosition(url + resultStr);
licensePlate.setImgStr(imgStr);
Call<LicensePlate> call = myAPIService.uploadLicensePlate(licensePlate);
call.enqueue(new Callback<LicensePlate>() {
#Override
public void onResponse(Call<LicensePlate> call, Response<LicensePlate> response) {
if(response.isSuccessful()){
Log.d("Status ", "照片上傳成功");
}else{
Log.d("Status ", "照片上傳失敗");
Log.d("response code ", response.code() + "");
}
}
#Override
public void onFailure(Call<LicensePlate> call, Throwable t) {
Log.d("Status ", "onFailure");
Log.d("Message ", t.getMessage());
}
});
}
};
private String bitmap2base64(Bitmap bitmap){
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream);
return Base64.encodeToString(outputStream.toByteArray(), Base64.DEFAULT).trim().replaceAll("\n", "").replaceAll("\r", "");
}
private Bitmap toBitmap(Image image) {
Image.Plane[] planes = image.getPlanes();
ByteBuffer yBuffer = planes[0].getBuffer();
ByteBuffer uBuffer = planes[1].getBuffer();
ByteBuffer vBuffer = planes[2].getBuffer();
int ySize = yBuffer.remaining();
int uSize = uBuffer.remaining();
int vSize = vBuffer.remaining();
byte[] nv21 = new byte[ySize + uSize + vSize];
//U and V are swapped
yBuffer.get(nv21, 0, ySize);
vBuffer.get(nv21, ySize, vSize);
uBuffer.get(nv21, ySize + vSize, uSize);
YuvImage yuvImage = new YuvImage(nv21, ImageFormat.NV21, image.getWidth(), image.getHeight(), null);
ByteArrayOutputStream out = new ByteArrayOutputStream();
yuvImage.compressToJpeg(new Rect(0, 0, yuvImage.getWidth(), yuvImage.getHeight()), 75, out);
byte[] imageBytes = out.toByteArray();
return BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length);
}
}
Camera
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);// 隐藏标题
DisplayMetrics metric = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metric);
int metricwidth = metric.widthPixels; // 屏幕宽度(像素)
int metricheight = metric.heightPixels; // 屏幕高度(像素)
try {
copyDataBase();
} catch (IOException e) {
e.printStackTrace();
}
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);// 竖屏
Configuration cf= this.getResources().getConfiguration(); //获取设置的配置信息
int noriention=cf.orientation;
requestWindowFeature(Window.FEATURE_NO_TITLE);// 隐藏标题
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);// 设置全屏
// // 屏幕常亮
getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON,
WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
setContentView(R.layout.activity_lpr2);
findView();
}
private void findView() {
surfaceView = (SurfaceView) findViewById(R.id.surfaceView);
re_c = (RelativeLayout) findViewById(R.id.re_c);
DisplayMetrics metric = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metric);
width = metric.widthPixels; // 屏幕宽度(像素)
height = metric.heightPixels; // 屏幕高度(像素)
if(myView==null)
{
if (isFatty)
{
myView = new LPRfinderView2(LPR2Activity.this, width, height, isFatty);
}
else
{
myView = new LPRfinderView2(LPR2Activity.this, width, height);
}
re_c.addView(myView);
}
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(LPR2Activity.this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
surfaceView.setFocusable(true);
//surfaceView.invali.date();
}
public void copyDataBase() throws IOException {
// Common common = new Common();
// 取得SK卡路徑/lpr.key
String dst = Environment.getExternalStorageDirectory().toString() + "/lpr.key";
File file = new File(dst);
if (!file.exists()) {
// file.createNewFile();
} else {
file.delete();
}
Log.d("File Name", file.toString());
try {
InputStream myInput = getAssets().open("lpr.key");
OutputStream myOutput = new FileOutputStream(dst);
byte[] buffer = new byte[1024];
int length;
while ((length = myInput.read(buffer)) > 0) {
myOutput.write(buffer, 0, length);
}
myOutput.flush();
myOutput.close();
myInput.close();
} catch (Exception e) {
System.out.println("lpr.key" + "is not found");
}
}
public void surfaceCreated(SurfaceHolder holder) {
if (mycamera == null) {
try {
mycamera = Camera.open();
} catch (Exception e) {
e.printStackTrace();
String mess = "打开摄像头失败";
Toast.makeText(getApplicationContext(), mess, Toast.LENGTH_LONG).show();
return;
}
}
if(mycamera!=null)
{
try {
mycamera.setPreviewDisplay(holder);
timer2 = new Timer();
if (timer == null)
{
timer = new TimerTask()
{
public void run()
{
if (mycamera != null)
{
try
{
mycamera.autoFocus(new AutoFocusCallback()
{
public void onAutoFocus(boolean success, Camera camera)
{
}
});
}
catch (Exception e)
{
e.printStackTrace();
}
}
};
};
}
timer2.schedule(timer, 500, 2500);
initCamera();
//mycamera.startPreview();
//mycamera.autoFocus(null);
} catch (IOException e) {
e.printStackTrace();
}
}
if(api==null)
{
api= new LPR();
String FilePath =Environment.getExternalStorageDirectory().toString()+"/lpr.key";
int nRet = api.Init(this,m_ROI[0], m_ROI[1], m_ROI[2], m_ROI[3], preHeight, preWidth,FilePath);
if(nRet!=0)
{
Toast.makeText(getApplicationContext(), "啟動失敗,請調整時間", Toast.LENGTH_SHORT).show();
Log.d("nRet ", nRet + "");
bInitKernal =false;
}
else
{
bInitKernal=true;
}
}
if(alertDialog==null){
alertDialog = new AlertDialog.Builder(this).create();
alertDialoginfo = new AlertDialog.Builder(this).create();
}
}
#Override
public void surfaceChanged(final SurfaceHolder holder, int format, int width, int height) {
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
try {
if (mycamera != null) {
mycamera.setPreviewCallback(null);
mycamera.stopPreview();
mycamera.release();
mycamera = null;
}
} catch (Exception e) {
}
if(bInitKernal){
bInitKernal=false;
api = null;
}
if(toast!=null){
toast.cancel();
toast = null;
}
if(timer2!=null){
timer2.cancel();
timer2=null;
}
if(alertDialog!=null)
{
alertDialog.dismiss();
alertDialog.cancel();
alertDialog=null;
}
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
try {
if (mycamera != null) {
mycamera.setPreviewCallback(null);
mycamera.stopPreview();
mycamera.release();
mycamera = null;
}
} catch (Exception e) {
e.printStackTrace();
}
if(bInitKernal)
{
bInitKernal=false;
api = null;
}
finish();
if(toast!=null){
toast.cancel();
toast=null;
}
if(timer2!=null){
timer2.cancel();
timer2=null;
}
if(alertDialog!=null)
{
alertDialog.cancel();
alertDialog=null;
}
}
return super.onKeyDown(keyCode, event);
}
#TargetApi(14)
private void initCamera() {
Camera.Parameters parameters = mycamera.getParameters();
List<Camera.Size> list = parameters.getSupportedPreviewSizes();
preWidth = list.get(4).width;
preHeight = list.get(4).height;
parameters.setPictureFormat(PixelFormat.JPEG);
parameters.setPreviewSize(preWidth,preHeight);
if (!bROI) {
int l,t,r,b;
l = 100;
r = width-100;
int ntmpH =(r-l)*58/100;
t = (height-ntmpH)/2;
b = t+ntmpH;
double proportion = (double) width / (double) preHeight;
double hproportion=(double)height/(double) preWidth;
l = (int) (l /proportion);
t = (int) (t /hproportion);
r = (int) (r /proportion);
b = (int) (b / hproportion);
m_ROI[0]=l;
m_ROI[1]=t;
m_ROI[2]=r;
m_ROI[3]=b;
bROI = true;
}
if (parameters.getSupportedFocusModes().contains(
parameters.FOCUS_MODE_AUTO))
{
parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);// 1连续对焦
}
mycamera.setPreviewCallback(LPR2Activity.this);
mycamera.setParameters(parameters);
mycamera.setDisplayOrientation(90); //一般機種
mycamera.startPreview();
}
public void onPreviewFrame(byte[] data, Camera camera) {
tackData = data;
Log.d("data length ", data.length + "");
ByteArrayInputStream bis = new ByteArrayInputStream(data);
resultStr = "";
if (!leaving&& bInitKernal ) {
Log.d("Status ", "開始判斷");
byte result[];//[] = new byte[10];
String res="";
result = api.VideoRec(tackData, preWidth, preHeight, 1);
Log.d("preWidth ", preWidth + "");
Log.d("preHeight", preHeight + "");
Log.d("width ", width + "");
Log.d("height", height + "");
try {
res = new String(result,"gb2312");
Log.d("try ", res);
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
Log.d("Exception ", e.getMessage());
e.printStackTrace();
}
Log.d("res ", res);
if(res!=null&&!"".equals(res.trim()))
{
Camera.Parameters parameters = mycamera.getParameters();
resultStr =res.trim();
if (resultStr != "") {
leaving = true;
//拍照音效
MediaActionSound sound = null;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) {
sound = new MediaActionSound();
sound.play(MediaActionSound.SHUTTER_CLICK);
}
Intent intent = new Intent();
intent.putExtra("strPltNo",resultStr);
setResult(2,intent);
finish();
}else{
Log.d("Status ", "未分配車牌號碼,請重拍");
}
}
}
}
#RequiresApi(api = Build.VERSION_CODES.CUPCAKE)
public String pictureName() {
String str = "";
Time t = new Time();
t.setToNow(); // 取得系统时间。
int year = t.year;
int month = t.month + 1;
int date = t.monthDay;
int hour = t.hour; // 0-23
int minute = t.minute;
int second = t.second;
if (month < 10)
str = String.valueOf(year) + "0" + String.valueOf(month);
else {
str = String.valueOf(year) + String.valueOf(month);
}
if (date < 10)
str = str + "0" + String.valueOf(date + "_");
else {
str = str + String.valueOf(date + "_");
}
if (hour < 10)
str = str + "0" + String.valueOf(hour);
else {
str = str + String.valueOf(hour);
}
if (minute < 10)
str = str + "0" + String.valueOf(minute);
else {
str = str + String.valueOf(minute);
}
if (second < 10)
str = str + "0" + String.valueOf(second);
else {
str = str + String.valueOf(second);
}
return str;
}
public void Leave(View view) {
Intent intent = new Intent();
intent.putExtra("strPltNo","");
setResult(3,intent);
finish();
}
}
CameraX Log
Camera Log
With regards to the image analysis resolution, the documentation of ImageAnalysis.Builder.setTargetResolution() states that:
The maximum available resolution that could be selected for an
ImageAnalysis is limited to be under 1080p.
So setting a size of 2560x800 won't work as you expect. In return CameraX seems to be selecting the maximum ImageAnalysis resolution that has the same aspect ratio you requested (2560/800 = 1280/400).
I'm new to Android programming and i'm trying to understand the control flow in android programs. I've been working on a program to log and display sensor data.
public class MainActivity extends ActionBarActivity implements SensorEventListener
This is the main class with onCreate(), btnStart.setOnClickListener(new OnClickListener(), btnStop.setOnClickListener(new OnClickListener(), onSensorChanged(SensorEvent event) which do most of the important tasks.
onCreate() has all this code:
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
title = (TextView)findViewById(R.id.titleView);
acc_x = (TextView)findViewById(R.id.acc_x_values);
acc_y = (TextView)findViewById(R.id.acc_y_values);
acc_z = (TextView)findViewById(R.id.acc_z_values);
x = (TextView)findViewById(R.id.acc_x);
y = (TextView)findViewById(R.id.acc_y);
z = (TextView)findViewById(R.id.acc_z);
btnStart = (Button)findViewById(R.id.button_start);
btnStop = (Button)findViewById(R.id.button_stop);
sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
mAccel = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
sensorManager.registerListener(this,sensorManager.getDefaultSensor(sensorType), 20000);
And the start and stop button funtionalities are defined here.
btnStart.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
startFlag = true;
String storepath = Environment.getExternalStorageDirectory().getPath();
System.out.println("Stored at" +storepath); // /storage/sdcard
Toast.makeText(getBaseContext(), "Started Recording Data and Storing at"+storepath, Toast.LENGTH_SHORT).show();
try {
myFile = new File(storepath + "/GaitApp/" + name.getText() + "_acc.csv");
myFile.createNewFile();
fOut = new FileOutputStream(myFile);
myOutWriter = new OutputStreamWriter(fOut);
myBufferedWriter = new BufferedWriter(myOutWriter);
myPrintWriter = new PrintWriter(myBufferedWriter);
} catch (Exception e) {
Toast.makeText(getBaseContext(), e.getMessage(), Toast.LENGTH_SHORT).show();
}
} //onclick
}); //startbutton
btnStop.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Toast.makeText(getBaseContext(), "Stopped Recording",Toast.LENGTH_SHORT).show();
startFlag = false;
try {
fOut.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}// onClick
}); // btnstopButton
onSensorChanged() is:
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
if(startFlag){
float[] values = event.values;
// Movement
float x_float = values[0];
float y_float = values[1];
float z_float = values[2];
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
String currentDateandTime = sdf.format(new Date());
long curTime = System.currentTimeMillis();
if ((curTime - lastUpdate) > 20) {
long diffTime = (curTime - lastUpdate);
lastUpdate = curTime;
x_float = event.values[0];
y_float = event.values[1];
z_float = event.values[2];
acc_x.setText(Float.toString(x_float));
acc_y.setText(Float.toString(y_float));
acc_z.setText(Float.toString(z_float));
String res=String.valueOf(currentDateandTime+", "+x_float)+", "+String.valueOf(y_float)+", "+String.valueOf(z_float+"\n");
Log.d("test", res);
for (int i = 0; i % 1 == 0; i++) {
if (startFlag) {
try{
fOut = new FileOutputStream(myFile);
myOutWriter = new OutputStreamWriter(fOut);
myBufferedWriter = new BufferedWriter(myOutWriter);
myPrintWriter = new PrintWriter(myBufferedWriter);
myPrintWriter.append(curTime - lastUpdate + ", " + x_float + ", " + y_float + ", " + z_float+ "\n");
}
catch (IOException e){
System.out.println("Exception: "+e);
}
//myPrintWriter.write(curTime - lastUpdate + ", " + x_float + ", " + y_float + ", " + z_float+ "\n");
} //startFlag is true
else {
try {
myOutWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
fOut.close();
} catch (IOException e) {
e.printStackTrace();
} // catch
} // else
} //for
} // if -- time
} // startFlag
} //accelerometer -- sensor
} // onSensorChanged
I'm trying to understand how the onSensorChanged() transfers control and in the process the acceleration data to onCreate() to be displayed and stored.
The onCreate method is only used to initially setup the view. Updates to the display must occur by deliberately invoking them. Furthermore updates to the UI must occur on the UI thread. Since the onSensorChanged call can occur asynchronously, if you wish sensor updates to trigger a display update you must send yourself a UI thread event. One option is to use a handler such as in the following untested code.
private Handler mHandler;
public void onCreate() {
mHandler = new Handler();
}
#Override
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
saveData(event);
final long currentTime = System.currentTimeMillis();
if (isResumed() && currentTime > (lasttime + SOME_DELAY)) {
lasttime = currentTime;
handler.post(new Runnable() {
#Override
public void run() {
updateDisplay(event);
}
});
}
}
}
private void updateDisplay(SensorEvent event) {
acc_x.setText(...);
acc_y.setText(...);
acc_z.setText(...);
x.setText(...);
y.setText(...);
z.setText(...);
}
Depending on your application you may wish to log your data in a service.
onSensorChanged() is the handler in this case. This call back function takes care of updating the UI and writing to the file.
My Problem is, that I capture audio by pressing the record button, but I can't see any audioFile in the specific path.
I capture sound, when I press the capture button:
private void startRecord()
{
ImageButton soundStop = (ImageButton)findViewById(R.id.soundstop);
soundStop.setVisibility(View.VISIBLE);
mediaRecorder = new MediaRecorder();
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
//mediaRecorder.setOutputFormat(sound);
//mediaRecorder.setOutputFile(soundFilePath);
//mediaRecorder.setAudioEncoder(audioEncoder);
//Log.d("hier ", "hier" + soundFilePath);
try {
mediaRecorder.prepare();
mediaRecorder.start();
}catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Toast.makeText(getApplicationContext(), "Aufnahme gestartet", Toast.LENGTH_LONG).show();
}
When I press the Stop Recording Button the file should be saved in the specific path. I tried it with Directory Musik and Downloads, but I can't find any file there
final OnClickListener soundRecordStop = new OnClickListener(){
#Override
public void onClick(View v) {
soundStop();
}
};
public void soundStop(){
SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yyyy hh:mm:ss");
Timestamp time = new Timestamp(System.currentTimeMillis());
String actualTime = sdf.format(time);
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
String name = sharedPreferences.getString("soundformat", "format");
int audioEncoder = sharedPreferences.getInt("audioEncoder", Property.getAudioEncoderInt());
String dateiendung = ".aac";
int sound = 6;
if(name == "aac"){
dateiendung = ".aac";
sound = 6;
} else if(name == "amr_nb"){
dateiendung = ".3gp";
sound = 3;
}
else if( name == "amr_wb"){
dateiendung = ".3gp";
sound = 4;
}
else if( name == "default" ){
dateiendung = ".default";
sound = 0;
}
else if( name == "mpeg"){
dateiendung = ".mp4";
sound = 2;
}
else if( name == "gpp" ){
Log.d("in gpp", "in gpp");
dateiendung = ".3gp";
sound = 1;
}
soundFile = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
soundFilePath = soundFile.getAbsolutePath() + actualTime + dateiendung;
Log.d("hier ", "hier1" + mediaRecorder);
if(mediaRecorder != null){
Log.d("hier ", "hier2" + mediaRecorder);
try {
//mediaRecorder.prepare();
mediaRecorder.stop();
mediaRecorder.release();
//mediaRecorder = null;
Log.d("hier ", "hier4" + mediaRecorder);
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
mediaRecorder.setOutputFormat(sound);
mediaRecorder.setOutputFile(soundFilePath);
Log.d("hier ", "hier2");
String pfad = soundFile.getAbsolutePath();
Toast.makeText(getApplicationContext(), "Aufnahme in " + pfad + " gespeichert", Toast.LENGTH_LONG).show();
ImageButton soundStop = (ImageButton)findViewById(R.id.soundstop);
soundStop.setVisibility(View.INVISIBLE);
}
The path seems to be correct: pfad /storage/sdcard0/Download17.07.2014 11:55:58.aac
Thanks for the comment the missing File Separator wasn't intentionally. I insert the missing Separator in Order to save the audio File in Downloads Directory. But no File nevertheless 😑
Please help me to find my file ;)
I have an issue when I am trying to download a file from server using FTP. I need to display seek-bar status of downloading file and download speed of the Internet. I am able to display seek-bar status and speed of the Internet for HTTP, but for FTP I am not able to perform that same task. In the attached image below I need to display seek-bar and network speed for FTP and HTTP. Below is the source code I used for HTTP and FTP. I don't know where I missed it?
HTTP Code:
class DownloadFileAsync extends AsyncTask<String, String, String> { //see the summary of asyncTask
long duration, pk;
private boolean sleep = false;
private HashMap<String, Object> map;
private ProgressBar bar;
private TextView real_time, test_avg, peak, status;
private ImageView pp;
//constructor
public DownloadFileAsync(HashMap<String, Object> map) {
this.map = map;
bar = (ProgressBar) map.get("bar");
// trans = (TextView) map.get("trans");
//real_time = (TextView) map.get("real_time");
test_avg = (TextView) map.get("test_avg");
//peak = (TextView) map.get("peak");
status = (TextView) map.get("status");
pp = (ImageView) map.get("pp");
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected String doInBackground(String... aurl) {
int count = 0;
try {
updateUI(pp, R.drawable.pause);
updateUI(status, "Connecting");
URL url = new URL(map.get("url").toString());
URLConnection conexion = url.openConnection();
conexion.connect();
final int lenghtOfFile = conexion.getContentLength();
InputStream input = new BufferedInputStream(url.openStream());
updateUI(status, "Connected");
OutputStream output = new FileOutputStream(Environment.getExternalStorageDirectory()
+ File.separator
+ Info.getInfo(con).HTTP_DOWNLOAD_FILE_NAME);
byte data[] = new byte[1024];
long total = 0;
final long started = System.currentTimeMillis();
long sleepingTime= 0;
System.out.println("started time --"+started);
updateUI(status, "Downloading");
while ((count = input.read(data)) != -1) {
while (sleep) {
Thread.sleep(1000);
sleepingTime +=1000;
}
total += count;
final int progress = (int) ((total * 100) / lenghtOfFile);
final long speed = total;
duration = ((System.currentTimeMillis() - started)-sleepingTime) / 1000;
runOnUiThread(new Runnable() {
public void run() {
bar.setProgress(progress);
// trans.setText("" + progress);
//duration = ((System.currentTimeMillis() - started)-sleepingTime) / 1000;
//real_time.setText(duration + " secs");
if (duration != 0) {
test_avg.setText((speed / duration) / 1024 + " kbps");
if (pk <= (speed / duration) / 1024)
{
pk = (speed / duration) / 1024;
}
//peak.setText(pk + " kbps");
}
}
});
output.write(data, 0, count);
}
output.flush();
output.close();
input.close();
updateUI(status, "Success");
}
catch (final Exception e) {
e.printStackTrace();
updateUI(status, "Failed");
}
updateUI(pp, R.drawable.resume);
return null;
}
private void updateUI(final TextView tv, final String str) {
runOnUiThread(new Runnable() {
public void run() {
tv.setText(str);
}
});
}
private void updateUI(final ImageView iv, final int id) { // may create problem
runOnUiThread(new Runnable() {
public void run() {
iv.setImageResource(id);
}
});
}
public void gotosleep(boolean val) {
sleep = val;
}
public boolean areYouSleeping() {
return sleep;
}
#Override
protected void onPostExecute(String unused) {
try {
//System.out.println("Info.getInfo(con).data.indexOf(map)==="+Info.getInfo(con).data.indexOf(map)+" map "+map);
if (!PARALLEL_MODE //for sequence mode
&& (Info.getInfo(con).data.indexOf(map) + 1) <= Info.getInfo(con).data.size()
&& testRunning) {
/*System.out.println("Info.getInfo(con).data.indexOf(map) + 1 "+Info.getInfo(con).data.indexOf(map) + 1
+" Info.getInfo(con).data.size() "+Info.getInfo(con).data.size()+" testRunning "+testRunning);
System.out.println("Info.getInfo(con).data.indexOf(map)==="+Info.getInfo(con).data.indexOf(map)+" map "+map);*/
System.out.println("asynclist "+asynclist.size());
asynclist.remove(0); //asynclist contains objects of (downloadAsync(map))
if(asynclist.size() > 0){
System.out.println("tlist in post execute+++"+tlist);
//DownloadFileAsync dfa = new DownloadFileAsync(tlist.get(0));
DownloadFileAsync dfa = (DownloadFileAsync) asynclist.get(0);
dfa.execute();
tlist.remove(0);
}
else{
startTests();
}
}
else if (PARALLEL_MODE && stopCount < asynclist.size() && testRunning) { //for parallel mode
System.out.println("stopCount before condition= " + stopCount);
if (stopCount == asynclist.size() -1 && testRunning) {
System.out.println("stopCount inside 1st condition= " + stopCount);
stopCount = 0;
// stopTests(0);
startTests();
System.out.println("Tests Started");
}
else {
stopCount++;
System.out.println("stopCount after increment = " + stopCount);
;
}
}
}
catch (Exception ed) {
ed.printStackTrace();
go.setText(R.string.go);
//testRunning = false;
}
}
}
For FTP:--
class FTPAsync extends AsyncTask<String, String, String> {
//private int mode = -1;
//added
long duration, pk;
private boolean sleep1 = false;
private HashMap<String, Object> map;
private ProgressBar bar;
private TextView real_time, test_avg, peak, status;
private ImageView pp;
//
public FTPAsync(int mode) {
// this.mode = mode;
}
//added
public FTPAsync(HashMap<String, Object> map) {
//Toast.makeText(con, "ftpAsync constructer is called" ,Toast.LENGTH_SHORT).show();
this.map = map;
bar = (ProgressBar) map.get("bar");
// trans = (TextView) map.get("trans");
//real_time = (TextView) map.get("real_time");
test_avg = (TextView) map.get("test_avg");
//peak = (TextView) map.get("peak");
status = (TextView) map.get("status");
pp = (ImageView) map.get("pp");
}
//
#Override
protected void onPreExecute() {
//Toast.makeText(con, "onPreExecute() is called" ,Toast.LENGTH_SHORT).show();
super.onPreExecute();
}
#Override
protected String doInBackground(String... arg0) {
int count = 0;
FTPClient ObjFtpCon = new FTPClient();
//Toast.makeText(con, "FTPasync doInBackground() is called" ,Toast.LENGTH_SHORT).show();
try {
runOnUiThread(new Runnable() {
public void run() {
bar.setProgress(0);
//real_time.setText(0 + " secs");
//test_avg.setText(0+ " kbps");
//peak.setText(0+" kbps");
}
});
updateUI(pp, R.drawable.pause);
//ObjFtpCon.connect("ftp.customhdclips.com");
ObjFtpCon.connect("ftp."+map.get("url").toString());
updateUI(status, "Connecting");
//if (ObjFtpCon.login("fstech#customhdclips.com", "fstech123")) {
if (ObjFtpCon.login(map.get("username").toString(), map.get("password").toString())) {
updateUI(status, "Connected");
// toast("Connected to FTP Server : ftp.customhdclips.com");
ObjFtpCon.enterLocalPassiveMode(); // important!
ObjFtpCon.cwd("/");// to send the FTP CWD command to the server, receive the reply, and return the reply code.
//if (mode == 0) {
if(Integer.parseInt((map.get("oprn").toString()))== 0){
// Download
System.out.println("download test is called");
File objfile = new File(
Environment.getExternalStorageDirectory()
+ File.separator + "/logo.png");
objfile.createNewFile();
FileOutputStream objFos = new FileOutputStream(objfile);
boolean blnresult = ObjFtpCon.retrieveFile("/logo.png",
objFos);
objFos.close();
if (blnresult) {
// toast("Download succeeded");
// toast("Stored at : " +
// objfile.getAbsolutePath());
}
}
else {
// Upload
System.out.println("upload test is called");
//Toast.makeText(con, "upload FTP test is called", Toast.LENGTH_SHORT).show();
//ContextWrapper context = null;
//assetManager= context.getAssets();
assetManager = getResources().getAssets();
input1 = assetManager.open("hello.txt");
final long started = System.currentTimeMillis();
int size = input1.available();
//byte[] buffer = new byte[size];
byte dataByte[] = new byte[1024];
//input1.read(buffer);
//String data = "ZK DATA TESTER TEST DATA1sdfsdf";
String data = input1.toString();
System.out.println("dat value is........"+data);
final int lenghtOfFile = data.getBytes().length;
//final int lenghtOfFile = input1.getBytes().length;
System.out.println("length of file....."+lenghtOfFile);
ByteArrayInputStream in = new ByteArrayInputStream(
data.getBytes());
//toast("Uploading /test.txt");
//Toast.makeText(con,"File Size : " +data.getBytes().length + " bytes",Toast.LENGTH_SHORT).show();
//byte b[] = new byte[1024];
long total = 0;
long sleepingTime= 0;
System.out.println("started time --"+started);
updateUI(status, "Uploading");
while ((count = in.read(dataByte)) != -1)
{
System.out.println("read value is...."+in.read(dataByte));
while (sleep1) {
Thread.sleep(1000);
System.out.println("ftp upload is in sleeping mode");
sleepingTime +=1000;
}
System.out.println("Total count --"+count);
total += count;
System.out.println("Only Total --"+total);
final int progress = (int) ((total * 100) / lenghtOfFile);
final long speed = total;
//duration = ((System.currentTimeMillis() - started)-sleepingTime) / 1000;
boolean result = ObjFtpCon.storeFile("/test.txt", input1);
//boolean result = ObjFtpCon.storeFile(map.get("file_address").toString()+"/test.txt", input1);
duration = ((System.currentTimeMillis() - started)-sleepingTime) / 1000;
runOnUiThread(new Runnable() {
public void run() {
bar.setProgress(progress);
// trans.setText("" + progress);
//duration = ((System.currentTimeMillis() - started)-sleepingTime) / 1000;
//duration = ((System.currentTimeMillis() - started)-sleepingTime) / 1000;
//real_time.setText(duration + " secs");
if (duration != 0) {
test_avg.setText((((speed / duration)*1000)*0.0078125)
+ " kbps");
/*if (pk <= (speed / duration) / 1024) {
pk = (speed / duration) / 1024;
}*/
if (pk <= ((speed / duration)*1000)*0.0078125) {
pk = (long)(((speed / duration)*1000)*0.0078125);
}
//peak.setText(pk + " kbps");
}
}
});
//in.close();
if (result) {
updateUI(status, "Uploaded");
// toast("Uploading succeeded");
// toast("Uploaded at /test.txt");
//duration = ((System.currentTimeMillis() - started)-sleepingTime) / 1000;
System.out.println("curreent time..... "+System.currentTimeMillis());
System.out.println("started time --"+started);
System.out.println("sleep tome...."+sleepingTime);
System.out.println("duration is....."+duration);
/*runOnUiThread(new Runnable() {
public void run() {
bar.setProgress(progress);
// trans.setText("" + progress);
//duration = ((System.currentTimeMillis() - started)-sleepingTime) / 1000;
real_time.setText(duration + " secs");
if (duration != 0) {
test_avg.setText((speed / duration) / 1024
+ " kbps");
if (pk <= (speed / duration) / 1024) {
pk = (speed / duration) / 1024;
}
peak.setText(pk + " kbps");
}
}
});*/
}
/*while(!result){Thread.sleep(1000);}*/
}
in.close();
}
}
else{
System.out.println("password entered is incorrect");
//Toast.makeText(con, "Username or/and password is incorrect", Toast.LENGTH_SHORT).show();
}
}
catch (Exception e) {
e.printStackTrace();
// toast(e.getLocalizedMessage());
}
try {
ObjFtpCon.logout();
ObjFtpCon.disconnect();
}
catch (IOException e) {
e.printStackTrace();
// toast(e.getLocalizedMessage());
}
return null;
}
#override
protected void onPostExecute(String unused) {
try {
//System.out.println("Info.getInfo(con).data.indexOf(map)==="+Info.getInfo(con).data.indexOf(map)+" map "+map);
if (!PARALLEL_MODE //for sequence mode
&& (Info.getInfo(con).data.indexOf(map) + 1) <= Info.getInfo(con).data.size()
&& testRunning) {
System.out.println("ftpasynclist "+ftpasynclist.size());
ftpasynclist.remove(0); //asynclist contains objects of (FTPAsync(map))
if(ftpasynclist.size() > 0){
System.out.println("tlist in post execute+++"+ftplist);
//DownloadFileAsync dfa = new DownloadFileAsync(tlist.get(0));
FTPAsync dfa = (FTPAsync)ftpasynclist.get(0);
dfa.execute();
ftplist.remove(0);
}
else{
startTests();
}
}
else if (PARALLEL_MODE //for parallel mode
&& ftpStopCount <ftpasynclist.size()
&& testRunning) {
System.out.println("stopCount before condition= " +ftpStopCount);
if (ftpStopCount == ftpasynclist.size() -1 && testRunning) {
System.out.println("stopCount inside 1st condition= " + ftpStopCount);
ftpStopCount = 0;
// stopTests(0);
startTests();
System.out.println("Tests Started");
}
else {
ftpStopCount++;
System.out.println("stopCount after increment = " + ftpStopCount);
;
}
}
}
catch (Exception ed) {
ed.printStackTrace();
go.setText(R.string.go);
//testRunning = false;
}
super.onPostExecute(unused);
}
private void updateUI(final TextView tv, final String str) {
runOnUiThread(new Runnable() {
public void run() {
tv.setText(str);
}
});
}
private void updateUI(final ImageView iv, final int id) { // may create problem
runOnUiThread(new Runnable() {
public void run() {
iv.setImageResource(id);
}
});
}
public void gotosleep(boolean val) {
sleep1 = val;
}
public boolean areYouSleeping() {
return sleep1;
}
}