Does anyone know how to see the progress (in percent) of an upload in a multipart upload in Amazon S3?
I would do it like this:
MultipleFileUpload transfer = transferManager.uploadDirectory(mybucket, null, new File(localSourceDataFilesPath), false);
// blocks the thread until the upload is completed
showTransferProgress(transfer);
Then in showTransferProgress, I would create a block the upload using a sleep, and do the math every X seconds:
private void showTransferProgress(MultipleFileUpload xfer) {
while (!xfer.isDone()) {
// some logic to wait so you don't do the math every second like a Thread.sleep
TransferProgress progress = xfer.getProgress();
long bytesTransferred = progress.getBytesTransferred();
long total = progress.getTotalBytesToTransfer();
Double percentDone = progress.getPercentTransferred();
LOG.debug("S3 xml upload progress...{}%", percentDone.intValue());
LOG.debug("{} bytes transferred to S3 out of {}", bytesTransferred, total);
}
// print the final state of the transfer.
TransferState xferState = xfer.getState();
LOG.debug("Final transfer state: " + xferState);
}
this line is what you are looking for:
Double percentDone = progress.getPercentTransferred();
Hi guys here is is my final version
private void awsHoldUntilCompletedAndShowTransferProgress(Upload upload) throws InterruptedException, AmazonClientException {
TransferProgress tProgress = upload.getProgress();
long totalSize = tProgress.getTotalBytesToTransfer();
long bPrevious = 0;
int timerSec = Math.toIntExact(Math.round(Math.sqrt(totalSize / 1024 / 1024) / 4));// calculate based on file size
if (timerSec > 60) {// no longer than 60 second per loop
timerSec = 60;
}
while (!upload.isDone()) {
long bTransferred = tProgress.getBytesTransferred();
String strMbps = Double.valueOf((((bTransferred - bPrevious) / timerSec) / 1024) / 1024).toString() + " MBps";
String strTransfered = bTransferred + " bytes";
if (bTransferred > 1024) {
strTransfered = Double.valueOf((bTransferred / 1024) / 1024).toString() + " MB";
}
log.info("Upload progress: "
+ strTransfered
+ " / "
+ FileUtils.byteCountToDisplaySize(totalSize) + " - "
+ Math.round(tProgress.getPercentTransferred()) + "% "
+ strMbps);
bPrevious = bTransferred;
TimeUnit.SECONDS.sleep(timerSec);
}
Transfer.TransferState transferState = upload.getState();
log.info("Final transfer state: " + transferState);
if (transferState == Transfer.TransferState.Failed) {
throw upload.waitForException();
}
}
and here is where I call the code above from
..stuff...
TransferManager tm = TransferManagerBuilder
.standard()
.withS3Client(s3Client)
.build();
LocalDateTime uploadStartedAt = LocalDateTime.now();
log.info("Starting to upload " + FileUtils.byteCountToDisplaySize(fileSize));
Upload up = tm.upload(bucketName, file.getName(), file);
awsHoldUntilCompletedAndShowTransferProgress(up);
log.info("Time consumed: " + DurationFormatUtils.formatDuration(Duration.between(uploadStartedAt, LocalDateTime.now()).toMillis(), "dd HH:mm:ss"));
this works, but may be a better way to do this
TransferManager tm = TransferManagerBuilder
.standard()
.withS3Client(s3Client)
.build();
PutObjectRequest request = new PutObjectRequest(bucketName, file.getName(), file);
ProgressListener progressListener = new ProgressListener() {
#Override
public void progressChanged(com.amazonaws.event.ProgressEvent progressEvent) {
bytesUploaded += progressEvent.getBytesTransferred();// add counter
if (bytesUploaded > byteTrigger) {
if ((bytesUploaded + sizeRatio) < fileSize) {
byteTrigger = bytesUploaded + sizeRatio ;
} else {
byteTrigger = bytesUploaded + (sizeRatio / 6);// increase precision approaching the end
}
String percent = new DecimalFormat("###.##").format(bytesUploaded * 100.0 / fileSize);
log.info("Uploaded: " + FileUtils.byteCountToDisplaySize(bytesUploaded) + " - " + percent + "%");
}
}
};
request.setGeneralProgressListener(progressListener);
Upload upload = tm.upload(request);
log.info("starting upload");
upload.waitForUploadResult();
log.info("Upload completed");
Related
i want to split pdf to image file by page, but i got Warning: You did not close a PDF Document looping when renderImageWithDPI
Still have warning
UPDATE CODE :
public void splitImage(PDDocument document, File checkFile, File theDirSplit, String fileExtension, File theDir, File watermarkDirectory, int numberOfPages)
throws InvalidPasswordException, IOException {
String fileName = checkFile.getName().replace(".pdf", "");
int dpi = 300;
if (theDirSplit.list().length < numberOfPages)
{
for (int i = 0; i < numberOfPages; ++i)
{
if (i == numberOfPages)
break;
if (theDirSplit.list().length != numberOfPages)
{
File outPutFile = new File(theDirSplit + Constan.simbol + fileName + "_" + (i + 1) + "." + fileExtension);
document = PDDocument.load(checkFile);
PDFRenderer pdfRenderer = new PDFRenderer(document);
BufferedImage bImage = pdfRenderer.renderImageWithDPI(i, dpi, ImageType.RGB);
ImageIO.write(bImage, fileExtension, outPutFile);
}
// splitService.watermark(outPutFile, (i + 1), watermarkDirectory, "pdf");
}
document.close();
//System.out.println("Converted Images are saved at -> " + theDirSplit.getAbsolutePath());
}
System.out.println("Done Partial SPlit");
/*
* int i = 1; while (iterator.hasNext()) { PDDocument pd = iterator.next();
* pd.save(theDirSplit + Constan.simbol + i++ + ".pdf"); }
* System.out.println("Multiple PDF’s created");
*/
}
error looping
total warning same with number of pages...
i already try to close but not work, this process make my server java.lang.OutOfMemoryError: Java heap space
update :
else if ("pdf".equalsIgnoreCase(typeFile)) {
System.out.println(
"target file " + downloadPath + R_OBJECT_ID + Constan.simbol + R_OBJECT_ID + "." + typeFile);
//get jumlah halaman
try(PDDocument document = PDDocument.load(checkFile)){
File theDirSplit = new File(theDir.getAbsolutePath() + Constan.simbol + "splitImage");
createFolder(theDirSplit);
String fileExtension = "jpeg";
File watermarkDirectory = new File(theDir.getAbsolutePath() + Constan.simbol + "watermarkImage");
createFolder(watermarkDirectory);
// split 2 page image
if (theDirSplit.list().length <= document.getNumberOfPages()) {
try {
splitImage(document,checkFile, theDirSplit, fileExtension, theDir, watermarkDirectory, document.getNumberOfPages()/2);
} catch (IOException e) {
System.out.println("ERROR SPLIT PDF " + e.getMessage());
e.printStackTrace();
}
}
res.setTotalPages(document.getNumberOfPages());
document.close();
return new ResponseEntity<>(res, HttpStatus.OK);
}
} else {
res.setTotalPages(1);
return new ResponseEntity<>(res, HttpStatus.OK);
}
this is code to call split method....
This is somewhat lost from the question, but the cause was failing to close the documents generated by splitter.split().
I debugging my application then I tried clicking twice and fast on the pretty dialog button and it print twice I expect that even I clicked twice it will not print twice.
I tried error handler codes but it was not working.
prettyDialog.addButton("YES",
R.color.navy_blue,
R.color.gold_yellow,
new PrettyDialogCallback() {
#Override
public void onClick() {
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
raw_serial = String.valueOf(Build.SERIAL);
serial_final = raw_serial.substring(raw_serial.length() - 7);
nf = new DecimalFormat("000000");
DateFormat dateFormat = new SimpleDateFormat("MMddyyyy");
Date date = new Date();
ticket_date = dateFormat.format(date).toString();
DateFormat datetimeformat = new SimpleDateFormat("HHmmss");
Date time = new Date();
ticket_time = datetimeformat.format(time).toString();
transaction_no = serial_final + ticket_date + ticket_time + nf.format(setting_last_transaction_no);
trace_no = merchant_code + serial_final + ticket_date + ticket_time + nf.format(ref_trace_no);
print_card_no = Cardno.substring(Cardno.length() - 4);
String print_balance;
print_balance = "P" + String.valueOf(Balance);
int balancespace = 0;
int balancelength = 0;
balancelength = print_balance.length();
balancespace = 13 - balancelength;
for (int j = 0; j < balancespace; j++) {
print_balance = " " + print_balance;
}
int print = PrinterInterface.open();
Log.e("print", String.valueOf(print));
int querystatus = PrinterInterface.queryStatus();
Log.e("querystatus", String.valueOf(querystatus));
DateFormat dateformatforprint = new SimpleDateFormat("MMM.dd,yyyy");
Date dateformatprint = new Date();
String datetoprint = dateformatforprint.format(dateformatprint).toString();
DateFormat timeformattoprint = new SimpleDateFormat("HH:mm");
Date timeformat = new Date();
String timetoprint = timeformattoprint.format(timeformat).toString();
String finalStation = "";
Log.e("asdasd", "asdasd");
if (print >= 0) {
byte[] arryTitle = null;
byte[] arryTrx = null;
byte[] arrySubtitle = null;
byte[] arryBody1 = null;
byte[] arryspace1 = null;
byte[] arryFooter = null;
//test
try {
arryTitle = ("\n" + "TRIPKO" + "\n" + "\n").getBytes("UTF-8");
arryTrx = ("TRX: " + transaction_no + "\n" +
trace_no + "\n").getBytes("UTF-8");
arrySubtitle = ("Date & Time : " + datetoprint + " " + timetoprint + "\n" +
"Merchant Name: " + subcompany_name.toUpperCase() + "\n" +
"Branch : " + terminal_name.toUpperCase() + "\n" +
"-------------------------------" + "\n" +
"\n").getBytes("UTF-8");
arryBody1 = ("Card No. : " + " **** **** **** " + print_card_no + "\n" +
"Trans Type : " + " " + type_name.toUpperCase() + "\n" +
"Current Balance : " + print_balance + "\n" +
"-------------------------------" + "\n" +
"\n").getBytes("UTF-8");
arryFooter = ("Customer Service" + "\n"
+ "Hotline#: TRIPKO(678-1234)" + "\n" +
"\n").getBytes("UTF-8");
arryspace1 = "\n".getBytes("UTF-8");
} catch (Throwable e) {
e.printStackTrace();
}
begin();
if (querystatus == 1) {
writeLineBreak(20);
write(arryspace1);
alignment(1);
Fontsize(16);
boldFont(2);
doublewidth();
write(arryTitle);
backtonormal();
nextline();
Fontsize(0);
write(arryTrx);
alignment(0);
write(arrySubtitle);
write(arryBody1);
alignment(1);
write(arryFooter);
write(arryspace1);
write(arryspace1);
write(arryspace1);
write(arryspace1);
insertData(company_id,
subcompany_id,
terminal_id,
setting_control_no,
Cardno,
Balance,
transaction_no,
trace_no,
device_serial);
setting_last_transaction_no += 1;
ref_trace_no += 1;
updateTicket(String.valueOf(setting_last_transaction_no),
String.valueOf(ref_trace_no));
DBBackup();
end();
btnCheckBalance.setEnabled(true);
btnCheckBalance.setClickable(true);
Intent intent2 = new Intent(getContext(), UpdateSendingServices.class);
getActivity().startService(intent2);
} else {
//OpenNoPaper();
}
}
PrinterInterface.close();
}
});
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
totalBalance.setText("P 0.00");
btnCheckBalance.setEnabled(true);
btnCheckBalance.setClickable(true);
}
});
prettyDialog.dismiss();
}
})
.show();
I expect that it will not print twice even I clicked the "YES" pretty dialog button.
i think you can just do a trick like this
create a count variable count=0;. In button click, validate condition such that if(count==0) show dialog and make count = 1. (with this dialog will not open second time) while dismissing dialog make count = 0 again.
I think this will work
Hope it helps.
if(count == 0){
count = 1 ;
//showdialog process
}
and right before dismiss()
......
count = 0;
prettyDialog.dismiss();
I want a dispatcher thread that executes and retrieves results from a pool of worker threads. The dispatcher needs to continuously feed work to the worker threads. When ANY of the worker thread completes, the dispatcher needs to gather its results and re-dispatch (or create a new) worker thread. It seems to me like this should be obvious but I have been unable to find an example of a suitable pattern. A Thread.join() loop would be inadequate because that is really "AND" logic and I am looking for "OR" logic.
The best I could come up with is to have the dispatcher thread wait() and have the worker threads notify() when they are done. Though seems like I would have to guard against two worker threads that end at the same time causing the dispatcher thread to miss a notify(). Plus, this seems a little bit inelegant to me.
Even less elegant is the idea of the dispatcher thread periodically waking up and polling the worker thread pool and checking each thread to see if it has completed via isAlive().
I took a look at java.util.concurrent and didn't see anything that looked like it fit this pattern.
I feel that to implement what I mention above would involve a lot of defensive programming and reinventing the wheel. There's got to be something that I am missing. What can I leverage to implement this pattern?
This is the single-threaded version. putMissingToS3() would become the dispatcher thread and the capability represented in the uploadFileToBucket() would become the worker thread.
private void putMissingToS3()
{
int reqFilesToUpload = 0;
long reqSizeToUpload = 0L;
int totFilesUploaded = 0;
long totSizeUploaded = 0L;
int totFilesSkipped = 0;
long totSizeSkipped = 0L;
int rptLastFilesUploaded = 0;
long rptSizeInterval = 1000000000L;
long rptLastSize = 0L;
StopWatch rptTimer = new StopWatch();
long rptLastMs = 0L;
StopWatch globalTimer = new StopWatch();
StopWatch indvTimer = new StopWatch();
for (FileSystemRecord fsRec : fileSystemState.toList())
{
String reqKey = PathConverter.pathToKey(PathConverter.makeRelativePath(fileSystemState.getRootPath(), fsRec.getFullpath()));
LocalS3MetadataRecord s3Rec = s3Metadata.getRecord(reqKey);
// Just get a rough estimate of what the size of this upload will be
if (s3Rec == null)
{
++reqFilesToUpload;
reqSizeToUpload += fsRec.getSize();
}
}
long uploadTimeGuessMs = (long)((double)reqSizeToUpload/estUploadRateBPS*1000.0);
printAndLog("Estimated upload: " + natFmt.format(reqFilesToUpload) + " files, " + Utils.readableFileSize(reqSizeToUpload) +
", Estimated time " + Utils.readableElapsedTime(uploadTimeGuessMs));
globalTimer.start();
rptTimer.start();
for (FileSystemRecord fsRec : fileSystemState.toList())
{
String reqKey = PathConverter.pathToKey(PathConverter.makeRelativePath(fileSystemState.getRootPath(), fsRec.getFullpath()));
if (PathConverter.validate(reqKey))
{
LocalS3MetadataRecord s3Rec = s3Metadata.getRecord(reqKey);
//TODO compare and deal with size mismatches. Maybe go and look at last-mod dates.
if (s3Rec == null)
{
indvTimer.start();
uploadFileToBucket(s3, syncParms.getS3Bucket(), fsRec.getFullpath(), reqKey);
indvTimer.stop();
++totFilesUploaded;
totSizeUploaded += fsRec.getSize();
logOnly("Uploaded: Size=" + fsRec.getSize() + ", " + indvTimer.stopDeltaMs() + " ms, File=" + fsRec.getFullpath() + ", toKey=" + reqKey);
if (totSizeUploaded > rptLastSize + rptSizeInterval)
{
long invSizeUploaded = totSizeUploaded - rptLastSize;
long nowMs = rptTimer.intervalMs();
long invElapMs = nowMs - rptLastMs;
long remSize = reqSizeToUpload - totSizeUploaded;
double progessPct = (double)totSizeUploaded/reqSizeToUpload*100.0;
double mbps = (invElapMs > 0) ? invSizeUploaded/1e6/(invElapMs/1000.0) : 0.0;
long remMs = (long)((double)remSize/((double)invSizeUploaded/invElapMs));
printOnly("Progress: " + d2Fmt.format(progessPct) + "%, " + Utils.readableFileSize(totSizeUploaded) + " of " +
Utils.readableFileSize(reqSizeToUpload) + ", Rate " + d3Fmt.format(mbps) + " MB/s, " +
"Time rem " + Utils.readableElapsedTime(remMs));
rptLastMs = nowMs;
rptLastFilesUploaded = totFilesUploaded;
rptLastSize = totSizeUploaded;
}
}
}
else
{
++totFilesSkipped;
totSizeSkipped += fsRec.getSize();
logOnly("Skipped (Invalid chars): Size=" + fsRec.getSize() + ", " + fsRec.getFullpath() + ", toKey=" + reqKey);
}
}
globalTimer.stop();
double mbps = 0.0;
if (globalTimer.stopDeltaMs() > 0)
mbps = totSizeUploaded/1e6/(globalTimer.stopDeltaMs()/1000.0);
printAndLog("Actual upload: " + natFmt.format(totFilesUploaded) + " files, " + Utils.readableFileSize(totSizeUploaded) +
", Time " + Utils.readableElapsedTime(globalTimer.stopDeltaMs()) + ", Rate " + d3Fmt.format(mbps) + " MB/s");
if (totFilesSkipped > 0)
printAndLog("Skipped Files: " + natFmt.format(totFilesSkipped) + " files, " + Utils.readableFileSize(totSizeSkipped));
}
private void uploadFileToBucket(AmazonS3 amazonS3, String bucketName, String filePath, String fileKey)
{
File inFile = new File(filePath);
ObjectMetadata objectMetadata = new ObjectMetadata();
objectMetadata.addUserMetadata(Const.LAST_MOD_KEY, Long.toString(inFile.lastModified()));
objectMetadata.setLastModified(new Date(inFile.lastModified()));
PutObjectRequest por = new PutObjectRequest(bucketName, fileKey, inFile).withMetadata(objectMetadata);
// Amazon S3 never stores partial objects; if during this call an exception wasn't thrown, the entire object was stored.
amazonS3.putObject(por);
}
I think you are at right package. you should use ExecutorService API.
This removes burden of waiting and watching for thread's notification.
Example:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.Executors;
public class ExecutorEx{
static class ThreadA implements Runnable{
int id;
public ThreadA(int id){
this.id = id;
}
public void run(){
//To simulate some work
try{Thread.sleep(Math.round(Math.random()*100));}catch(Exception e){}
// to show message
System.out.println(this.id + "--Test Message" + System.currentTimeMillis());
}
}
public static void main(String args[]) throws Exception{
int poolSize = 10;
ExecutorService pool = Executors.newFixedThreadPool(poolSize);
int i=0;
while(i<100){
pool.submit(new ThreadA(i));
i++;
}
pool.shutdown();
while(!pool.isTerminated()){
pool.awaitTermination(60, TimeUnit.SECONDS);
}
}
}
And if you want to return something from your thread will need to implement Callable instead of Runnable(call() instead of run()) and collect returned values in Future object array, that you can iterate over later.
My issue: my android device is unable to connect to a public FTP server using URLConnection. However, when the device tried to connect to a public FTP server (anonymous for username and no password), it cannot retrieve the InputStream from urlConnection.getInputStream();.
I do not use FTPClient from Apache Commons library because the speed is quite limited... A related question regarding that limited speed with FTPClient is here
FTPClient's download is slower than URLConnection's download.
Whatever I tried with the urlString:
urlString = protocol+"://" + username+"#" +address+":"+port + filepath + file;
// ftp://anonymous#speedtest.tele2.net:21/100GB.zip
urlString = protocol+"://" + username+":" + password + "#" +address+":"+port + filepath + file;
// ftp://anonymous:#speedtest.tele2.net:21/100GB.zip
urlString = protocol+"://" + username+":" + "password" + "#" +address+":"+port + filepath + file;
// ftp://anonymous:password#speedtest.tele2.net:21/100GB.zip
urlString = protocol+"://" + address+":"+port + filepath + file;
// ftp://speedtest.tele2.net:21/100GB.zip
downloadAndBroadcastURL:after getinputStream is never got logged with open FTP servers. I also tried with these two public FTP servers:
ftp://speedtest.tele2.net/100GB.zip
ftp://ftp.funet.fi/dev/1GBnull
But it doesn't connect as well.
My code:
private void downloadAndBroadcastURL() {
beginTime = System.currentTimeMillis();
try {
String urlString;
if (username.equals("anonymous")){
urlString = protocol+"://" + username+"#" +address+":"+port + filepath + file;
} else {
urlString = protocol+"://" + username+":" + password + "#" +address+":"+port + filepath + file;
}
Log.d(TAG, "downloadAndBroadcastURL: "+ urlString);
URL url = new URL(urlString);
URLConnection urlConnection = url.openConnection();
Log.d(TAG, "downloadAndBroadcastURL:after connect ");
inputStream = new BufferedInputStream(urlConnection.getInputStream());
Log.d(TAG, "downloadAndBroadcastURL:after getinputStream");
/*******************************
The rest is about handling the input stream, the download...
*****************************/
long difference;
byte data[] = new byte[4094];
int count;
while ((count = inputStream.read(data)) != -1 && download) {
downloadCount += count;
long stopTime = System.currentTimeMillis();
difference = stopTime - beginTime;
if (difference > 1000 && download) {
currentSpeed = downloadCount / (difference / 1000L); //for precision, because difference can be more than 1000 sometimes
averageSpeed = (averageSpeed + currentSpeed) / 2;
Log.d(TAG, "Speed: " + downloadCount + " bytes/s. " + (downloadCount / 1024) + "kB/s " + (downloadCount / 128) + "kbit/s " + (downloadCount / 1048576) + "Mb/s " + ((downloadCount) / (1024 * 128)) + "Mpbs" + (downloadCount / 131072) + "Mbit/s difference:" + difference + "ms");
if (download) {
broadcastSpeed();
}
downloadCount = 0; //Resetoidaan määrä
beginTime = stopTime;
}
if (!download) {
Log.d(TAG, "downloadAndBroadcast: download stops");
clearInputStream();
}
}
clearInputStream();
} catch (Exception e) {
e.printStackTrace();
Log.d(TAG, "FAIL " + e.toString());
} finally {
Log.d(TAG, "downloadAndBroadcastURL: ");
clearInputStream();
Log.d(TAG, "downloadAndBroadcast: finally");
}
}
Does anyone have any idea? Thanks in advance!
I think there should be no difference in total time duration of play back of an audio file if we convert it between different formats.
For example if I record wave file of total time duration for 2 seconds, its size now is 20.3 MB . now i convert this wave file to mp3 file using ffmpeg latest build it becomes 1.35 mb in sizes. Now I get the time duration of the same converted MP3 file using below code.
public static String getDurationWithMp3Spi(File file)
throws UnsupportedAudioFileException, IOException, Exception {
AudioFileFormat fileFormat = AudioSystem.getAudioFileFormat(file);
System.out.println(" File for duration MP3 " + file.getAbsolutePath());
if (fileFormat instanceof TAudioFileFormat) {
Map<?, ?> properties = ((TAudioFileFormat) fileFormat).properties();
String key = "duration";
Long microseconds = (Long) properties.get(key);
int mili = (int) (microseconds / 1000);
int sec = (mili / 1000) % 60;
int min = (mili / 1000) / 60;
String mp3Len = null;
String mins = null;
String secs = null;
if (min == 0) {
mins = "00";
}
if (min < 10) {
mins = "0" + min;
}else{
mins = "" + min;
}
if (sec == 0) {
secs = "00";
}
if (sec < 10) {
secs = "0" + sec;
}else{
secs = ""+secs;
}
mp3Len = mins + ":" + secs;
System.out.println("time = " + min + ":" + sec);
return mp3Len;
} else {
throw new UnsupportedAudioFileException();
}
}
If I see in windows media player or any other player it will show the same duration as it is for original wave but when I get from this method it is different from originals and the difference is very big.
Is there in difference in time duration of audio file if it is converted from WAVE to MP3 or vice versa?
Any help please. the above code uses MP3SPI plugin.
the above method does the conversion and get the duration.
for (Iterator<FileItem> fileIter = fileList.iterator(); fileIter
.hasNext();) {
FileItem fileItem = fileIter.next();
// write file to disk to specified path
if (!fileItem.isFormField()) {
String fileName = fileItem.getName();
System.out.println(" file Name " + fileName);
// save file to desired destination
waveFileSavePath = processFolderAppendee(waveFileSavePath,
fileName);
File waveFile = new File(waveFileSavePath);
fileItem.write(waveFile);
Thread.sleep(100);
// do conversion
String mp3FileName = fileName.replace("wav", "mp3");
mp3Path = mp3Path + "/" + mp3FileName;
convertToMP3(servletContext, waveFileSavePath, mp3Path);
Thread.sleep(100);
// prepare data(s)
GuestMessagesForm guestMessageForm = prepareGuestMessageData(
accountId, waveFileSavePath, mp3Path);
PlayListMessagesForm playListMessageForm = preparePlayListMessageData(accountId);
// save data(s)
// this method calls duration
saveGuestMessage(guestMessageForm);
savePlayListMessage(playListMessageForm);
} else {
// do nothing
}
waveFileSavePath = servletContext.getRealPath(recordDir);
}