J'ai créé une application pour enregistreur vocal et je souhaite afficher la durée des enregistrements dans une liste. Je sauvegarde les enregistrements comme ceci:
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();
}
Comment puis-je obtenir la durée en secondes de ce fichier?
Merci d'avance
--- EDIT Je l'ai fait fonctionner, j'ai appelé MediaPlayer.getduration () à l'intérieur de la méthode MediaPlayer.setOnPreparedListener () afin qu'elle renvoie 0.
MediaMetadataRetriever
est un moyen léger et efficace de le faire. MediaPlayer
est trop lourd et peut entraîner des problèmes de performances dans des environnements très performants tels que le défilement, la pagination, la liste, etc.
De plus, Error (100,0)
peut se produire sur MediaPlayer
car il s’agit d’une opération lourde qui nécessite parfois un redémarrage continu.
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);
Essayez ceci pour obtenir la durée en millisecondes:
MediaPlayer mp = MediaPlayer.create(yourActivity, Uri.parse(pathofyourrecording));
int duration = mp.getDuration();
Ou mesurez le temps écoulé entre recorder.start()
et recorder.stop()
en nanosecondes:
long startTime = System.nanoTime();
// ... do recording ...
long estimatedTime = System.nanoTime() - startTime;
Essayez d'utiliser
long totalDuration = mediaPlayer.getDuration(); // to get total duration in milliseconds
long currentDuration = mediaPlayer.getCurrentPosition(); // to Gets the current playback position in milliseconds
Division sur 1000 pour convertir en secondes.
J'espère que cela vous a aidé.
Le moyen le plus rapide de le faire est via MediaMetadataRetriever
. Cependant, il y a un catch
si vous utilisez l'URI et le contexte pour définir la source de données, vous pourriez rencontrer un bogue https://code.google.com/p/Android/issues/detail?id=35794
La solution consiste à utiliser le chemin absolu du fichier pour extraire les métadonnées du fichier multimédia.
Ci-dessous l'extrait de code pour le faire
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));
}
Maintenant, vous pouvez convertir des millisecondes en un format lisible par l'homme en utilisant l'un des formats ci-dessous.
/**
* 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;
}
Avez-vous regardé Ringdroid ?. C'est assez léger et l'intégration est simple. Cela fonctionne aussi bien avec les fichiers multimédias VBR.
Pour votre problème avec l'obtention de la durée, vous pouvez faire quelque chose comme ci-dessous en utilisant Ringdroid.
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;
}
}
J'espère que cela pourra aider
Une fois le fichier écrit, ouvrez-le dans un MediaPlayer et appelez getDuration dessus.
Si le fichier audio provient de l'URL, attendez simplement que le message soit prêt:
mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
length = mp.getDuration();
}
});