Ich habe eine Sprachaufzeichnungs-App erstellt und möchte die Dauer der Aufnahmen in einer Listenansicht anzeigen. Ich speichere die Aufnahmen so:
MediaRecorder recorder = new MediaRecorder();
recorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
folder = new File(Environment.getExternalStorageDirectory()
+ File.separator + "Audio recordings");
String[] files = folder.list();
int number = files.length + 1;
String filename = "AudioSample" + number + ".mp3";
File output = new File(Environment.getExternalStorageDirectory()
+ File.separator + "Audio recordings" + File.separator
+ filename);
FileOutputStream writer = new FileOutputStream(output);
FileDescriptor fd = writer.getFD();
recorder.setOutputFile(fd);
try {
recorder.prepare();
recorder.start();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
Log.e(LOG_TAG, "prepare() failed");
e.printStackTrace();
}
Wie kann ich die Dauer dieser Datei in Sekunden erhalten?
Danke im Voraus
--- EDIT Ich habe es funktioniert, ich habe MediaPlayer.getduration () in der MediaPlayer.setOnPreparedListener () -Methode aufgerufen, also gab es 0 zurück.
MediaMetadataRetriever
ist eine einfache und effiziente Möglichkeit, dies zu tun. MediaPlayer
ist zu umfangreich und kann zu Leistungsproblemen in Hochleistungsumgebungen wie Scrollen, Paging, Auflisten usw. führen.
Außerdem könnte Error (100,0)
bei MediaPlayer
vorkommen, da dies sehr umfangreich ist und manchmal ein Neustart erforderlich ist.
Uri uri = Uri.parse(pathStr);
MediaMetadataRetriever mmr = new MediaMetadataRetriever();
mmr.setDataSource(AppContext.getAppContext(),uri);
String durationStr = mmr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
int millSecond = Integer.parseInt(durationStr);
Versuchen Sie dies entweder, um die Dauer in Millisekunden zu erhalten:
MediaPlayer mp = MediaPlayer.create(yourActivity, Uri.parse(pathofyourrecording));
int duration = mp.getDuration();
Oder messen Sie die verstrichene Zeit von recorder.start()
bis recorder.stop()
in Nanosekunden:
long startTime = System.nanoTime();
// ... do recording ...
long estimatedTime = System.nanoTime() - startTime;
Versuchen Sie es mit
long totalDuration = mediaPlayer.getDuration(); // to get total duration in milliseconds
long currentDuration = mediaPlayer.getCurrentPosition(); // to Gets the current playback position in milliseconds
Division auf 1000 in Sekunden konvertieren.
Hoffe das hat dir geholfen.
Am schnellsten geht es über MediaMetadataRetriever
. Es gibt jedoch einen catch
wenn Sie URI und Kontext verwenden, um eine Datenquelle festzulegen, können Sie auf Fehler .__ stoßen. https://code.google.com/p/Android/issues/detail?id=35794
Die Lösung verwendet den absoluten Dateipfad, um Metadaten der Mediendatei abzurufen.
Nachfolgend finden Sie das Code-Snippet
private static String getDuration(File file) {
MediaMetadataRetriever mediaMetadataRetriever = new MediaMetadataRetriever();
mediaMetadataRetriever.setDataSource(file.getAbsolutePath());
String durationStr = mediaMetadataRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
return Utils.formateMilliSeccond(Long.parseLong(durationStr));
}
Jetzt können Sie Millisekunden in ein vom Menschen lesbares Format konvertieren, indem Sie eines der folgenden Formate verwenden
/**
* Function to convert milliseconds time to
* Timer Format
* Hours:Minutes:Seconds
*/
public static String formateMilliSeccond(long milliseconds) {
String finalTimerString = "";
String secondsString = "";
// Convert total duration into time
int hours = (int) (milliseconds / (1000 * 60 * 60));
int minutes = (int) (milliseconds % (1000 * 60 * 60)) / (1000 * 60);
int seconds = (int) ((milliseconds % (1000 * 60 * 60)) % (1000 * 60) / 1000);
// Add hours if there
if (hours > 0) {
finalTimerString = hours + ":";
}
// Prepending 0 to seconds if it is one digit
if (seconds < 10) {
secondsString = "0" + seconds;
} else {
secondsString = "" + seconds;
}
finalTimerString = finalTimerString + minutes + ":" + secondsString;
// return String.format("%02d Min, %02d Sec",
// TimeUnit.MILLISECONDS.toMinutes(milliseconds),
// TimeUnit.MILLISECONDS.toSeconds(milliseconds) -
// TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(milliseconds)));
// return timer string
return finalTimerString;
}
Haben Sie sich Ringdroid angesehen ?. Es ist ziemlich leicht und die Integration ist einfach. Es funktioniert auch mit VBR-Mediendateien.
Für Ihr Problem beim Abrufen der Dauer möchten Sie vielleicht etwas wie Ringdroid verwenden.
public class AudioUtils
{
public static long getDuration(CheapSoundFile cheapSoundFile)
{
if( cheapSoundFile == null)
return -1;
int sampleRate = cheapSoundFile.getSampleRate();
int samplesPerFrame = cheapSoundFile.getSamplesPerFrame();
int frames = cheapSoundFile.getNumFrames();
cheapSoundFile = null;
return 1000 * ( frames * samplesPerFrame) / sampleRate;
}
public static long getDuration(String mediaPath)
{
if( mediaPath != null && mediaPath.length() > 0)
try
{
return getDuration(CheapSoundFile.create(mediaPath, null));
}catch (FileNotFoundException e){}
catch (IOException e){}
return -1;
}
}
Hoffentlich hilft das
Nachdem Sie die Datei geschrieben haben, öffnen Sie sie in einem MediaPlayer und rufen Sie getDuration auf.
Wenn das Audio von einer URL stammt, warten Sie einfach auf:
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
length = mp.getDuration();
}
});