helaruwan / android-daisy-epub-reader

Automatically exported from code.google.com/p/android-daisy-epub-reader
0 stars 0 forks source link

We need a way to play sections of MP3 audio correctly #52

Open GoogleCodeExporter opened 8 years ago

GoogleCodeExporter commented 8 years ago
Lots of full-audio DAISY books store their recorded audio in mp3 files. Often 
several sections are stored in a common mp3 file, where the starting and ending 
offsets are stored in the SMIL file which points to the mp3 audio. The SMIL 
file may also refer to text and other media to be displayed as the audio is 
played. (See the following web link for more information about the 
relationships between SMIL files and audio files in the DAISY 2.02 
http://www.daisy.org/z3986/specifications/daisy_202.html#smil )

The current version of DaisyReader simply sidesteps the challenge by taking 
advantage of the typical way the audio is stored in full-audio books. It plays 
the audio from the current offset until the end of the mp3 file. The current 
offset either comes from the automatic bookmark (created by DaisyReader to keep 
track of where it has reached in the current DAISY audio book) or from the 
clip-start attribute for the section selected by the user as they navigate 
around the book. 

The current approach is too limiting if we want to synchronize other media with 
the audio being played (i.e. the book being 'read') or for books that don't 
store the audio segments sequentially (the standard is flexible in how the 
audio is stored and referenced, read the following section of the DAISY 2.02 
standard for details: 2.3.4.1 The NCC - SMIL - Audio relationships )

The main technical limitations we have identified is the Android MediaPlayer 
does not accept an 'end' or 'play-until' parameter. Thanks to Nick Williamson 
at the RNIB, we have an experimental implementation that starts a separate 
timer in the program which sends a stop command to the MediaPlayer when the 
duration of the current segment has been reached or exceeded. However when we 
tested this 
design we noticed the audio is sometimes truncated and doesn't sound as smooth 
as we'd like.

Here are some additional ideas which might work. Each could be assessed and 
tested for practicality and suitability.
   1 SplitMp3Files Programmatically split the mp3 files into separate, discrete files each containing only one segment. We would also need to patch the information in the SMIL files to point to the discrete files.

   2 OverlayMp3Files Create a 'virtual' overlay which makes the mp3 file appear as if it finishes at the end of the current segment. Pass this overlay to the MediaPlayer which then plays it as if it's a real file. The MediaPlayer then stops at the 'end' of the overlay on the track.

   3 NativeMediaPlayer Create a custom MediaPlayer that allows us to specify when to finish playing the current audio. Several commercial development companies have created custom Media Players to allow more flexibility and control, we could do something similar.

I don't know enough at this stage to implement any of the 3 proposed approaches 
effectively (in terms of both time and quality of the results) contributions of 
ideas and code are welcome. 

Here are some links that may contain clues on how to improve our handling of 
the mp3 audio:
   * http://www.wiseandroid.com/post/2010/07/13/Intro-to-the-three-Android-Audio-APIs.aspx
   * http://mindtherobot.com/blog/624/android-audio-play-an-mp3-file-on-an-audiotrack/ 
   * A pair of related questions on stackoverflow.com which seem to have the same aim we have: http://stackoverflow.com/questions/5457094/android-how-to-stop-a-playing-media-mp3-in-specific-duration and http://stackoverflow.com/questions/5454452/android-how-to-stop-media-mp3-in-playing-when-specific-milliseconds-come
   * http://developer.android.com/reference/android/os/CountDownTimer.html as another way to possibly control the MediaPlayer
   * http://www.javazoom.net/projects.html JLayer and other related libraries for playing MP3 (and other audio formats) using Java. See http://www.streamhead.com/jlayer-java-mp3-decoder/ for an overview of using JLayer.
   * http://code.google.com/p/mp3transform/ is a newer version of J(ava)Layer
   * http://www.javaworld.com/javaworld/jw-11-2000/jw-1103-mp3.html (an older article from 2000 and for Java 1.3 but seems interesting and relevant)
   * http://stackoverflow.com/questions/6294807/calculate-mpeg-frame-length-ms if we decide to use JavaLayer and it's AdvancedPlayer then it provides a method that takes starting and ending frames, so we'd need to be able to calculate the correct values for each frame.
   * http://p-nand-q.com/download/split3pm.html however read the limitation about inaccuracies in the timing. Also the code is in C++

Original issue reported on code.google.com by julianharty on 28 Dec 2011 at 11:09

GoogleCodeExporter commented 8 years ago
The 
http://stackoverflow.com/questions/5454452/android-how-to-stop-media-mp3-in-play
ing-when-specific-milliseconds-come answer looks good.

Original comment by brito....@gmail.com on 12 Apr 2012 at 2:31