Firstly, appologies for the length and detail in this post, but I thought best to provide as much detail as possible.
I have several hundred video files that are mostly sourced from PAL dvd's. They have mostly been encoded as h264 and put into avi containers with the original ac3 soundtrack. I can't remember the precise command, but I used ffmpeg to acheive this. These have been mostly played on xbmc and in that capacity there have been no major issues. As myself and other family members have several iOS devices capable of playing this type of content, it would be good if I could transfer them to mp4 containers with aac audio for playback on those devices and still have them avaiable to play on xbmc.
I'm trying to create a simple script to achieve this. Without going into the detail of the script, basic function is as follows:
1) mux avi into mkv using mkvmerge
2) demux mkv into elemental streams using mkvextract (steps 1&2 seem to be necessary because I can't get step 3 to work extracting the elemental streams any other way)
3) Hack the h264 stream so that it appears to be level 4.1
4) encode ac3 stream to aac using ffmpeg
5) mux h264, aac, and ac3 streams into mp4 using mp4 box.
All this works correctly and I get a working mp4 file at the end. The resulting file does, however have audio sync issues. Now interstingly if I do ffmpeg -i on the original avi, it shows the frame rate as 29.97, not 25 as it should be as it's sourced from a PAL dvd. XBMC plays the video at 25fps and audio pretty much stays in sync.
Now, if I force mp4box to mux it at 25fps the audio starts in sync, but slowly drifts out and by the end of the movie, there is about a 1 sec diff.
Interestingly if I do MP4Box -info on my finished file, I get:
You'll notice that there is just over 1 second's difference between the duration of the audio and the video. It seems this is why the audio is getting out of sync. It seems that the duration of the video is calculated by using the total number of frames (which is given in mp4box -info) and dividing by fps.
* Movie Info *
Timescale 600 - Duration 01:51:49.086
Fragmented File no - 3 track(s)
File Brand M4V - version 0
Created: GMT Sun Jun 19 09:28:39 2011
File has root IOD
Scene PL 0xff - Graphics PL 0xff - OD PL 0xff
Visual PL: AVC/H264 Profile (0x15)
Audio PL: AAC Profile @ Level 2 (0x29)
No streams included in root OD
Name: Me, Myself and Irene
Cover Art: JPEG File
Track # 1 Info - TrackID 1 - TimeScale 25000 - Duration 01:51:48.000
Media Info: Language "Undetermined" - Type "vide:avc1" - 167700 samples
MPEG-4 Config: Visual Stream - ObjectTypeIndication 0x21
AVC/H264 Video - Visual Size 704 x 544 - Profile High @ Level 4.1
NAL Unit length bits: 32
Pixel Aspect Ratio 11133:34464 - Indicated track size 704 x 544
Track # 2 Info - TrackID 2 - TimeScale 48000 - Duration 01:51:49.034
Media Info: Language "Undetermined" - Type "soun:mp4a" - 314486 samples
MPEG-4 Config: Audio Stream - ObjectTypeIndication 0x40
MPEG-4 Audio AAC LC - 2 Channel(s) - SampleRate 48000
Synchronized on stream 1
Track # 3 Info - TrackID 3 - TimeScale 48000 - Duration 01:51:49.088
Media Info: Language "Undetermined" - Type "soun:ac-3" - 209659 samples
AC3 stream - Sample Rate 48000 - 2 channel(s) 16 bits per samples
One possible solution I have considered, is trying to determine the total number of frames before muxing to mp4, then calculate the fps based on that and the duration of the audio. In the case above the fps would be something like 24.99. I could then use this when muxing to mp4.
Does this seem a valid solution and would it work? If so, is there any way to determine the total number of frames at some earlier stage in the process(avi, mkv, or elemental) that can be used in a script?
Or, is there a better solution?
Thanks for any help,