2

[Summary]

  • Using splicer for C#.
  • Trying to add voice-over to an image.
  • Added single image and audio track to a timeline.
  • However, the audio is cut off in the rendered video, and the video is shorter than it should be.
  • I've checked the audio clip and it's full length and has no issues. No problem with the image either.
  • Note: I've recompiled the source-code of Splicer using a 1080p prx file for the WindowsMediaProfiles.HighQualityVideo profile. It works well. Though, could it be the cause of the problem?

[Background, what I've already done]

1

  • I can't use the AVIFileRenderer as the output file size is too large.
  • I can't use the default prx file for the WindowsMediaProfiles.HighQuality profile as the output result is too bad. -I downloaded the prx file from 'questions4steveb.co.uk'.

2

  • When adding the audio to the audio track (audioFileName), I'm specifying the 'clipEnd' parameter to the value I'm getting from MediaInspector.GetLength(audioFileName) / (double)TimelineBuilder.Units. (audioLen).
  • I've also tried not specifying that paramater at all but, the results are the same.

3

  • When adding the image to the video track (imgFileName), I'm specifying the 'clipEnd' parameter to the same value, 'audioLen'.
  • I've also tried using audioClip.Duration as the 'clipEnd' parameter for the image.

4

  • The audio file has no issues. It's an MPEG file, and plays its full duration when played separately in Windows. -The image file has no issues either, it's a JPEG file.

5

  • I've tried using different inputs from the image and voice overs. But same results unfortunately :/

[Code]

using (var timeLine = new DefaultTimeline(24)) {
                        var vidGroup1 = timeLine.AddVideoGroup("videoGroup1", 24, 24, txtImg.Properties.Size.Width, txtImg.Properties.Size.Height);
                        var vidTrack1 = vidGroup1.AddTrack();

                        var audioGroup = timeLine.AddAudioGroup("audioGroup1", 24);
                        var audioTrack1 = audioGroup.AddTrack();

                        var audioFileName = await txtSpeech.SynthesizeSpeechAsync(text);
                        var audioLen = MediaInspector.GetLength(audioFileName) / (double)TimelineBuilder.Units;

                        var audioClip = audioTrack1.AddAudio(audioFileName, InsertPosition.Absolute, 0, 0, audioLen);
                        MessageBox.Show("Added audio. Len = " +audioLen);

                        var imgFileName = await txtImg.RenderImageAsync(text);
                        vidTrack1.AddImage(imgFileName, InsertPosition.Absolute, 0, 0, audioLen);
                        MessageBox.Show("Added image");

                        MessageBox.Show("Render started");
                        _renderer = new WindowsMediaRenderer(timeLine, "output.wmv", WindowsMediaProfiles.HighQualityVideo);
                        _renderer.BeginRender(hello, null);
                    } 

        // callback function

        private void hello(IAsyncResult ar) {
            _renderer.EndRender(ar);
            _renderer.Dispose();
            Process.Start("output.wmv");
            MessageBox.Show("Render complete");
        }

[Results]

  • Expected results are: The video plays for the duration of the audio track.
  • Actual results: The audio doesn't play fully and is cut off towards the end of the video. The video also ends when the audio does, so its shorter than it needs to be.

Example: If the voice-over audio reads: "I had a great day at a waterpark / outdoor pool and towards the afternoon." The playback of the audio stops at 'towards'.

Temporary (and highly imperfect) solution that I have right now: I just multiply the 'audioLen' variable by 1.5 or 2. That plays out the entire audio track. However, it adds padding to the audio towards the end. So the video is longer than it needs to be.

This might indicate that the audio length I'm attaining is incorrect. Or I'm attaining it incorrectly.

[Modified code as per suggestion (not working)]

                    var text = "My bother spent some time in Japan and one of the things he missed a lot while he was there was Salt & Vinegar chips. So we sent him some. He tried to share them with folks there in Japan and they thought they were the most disgusting thing ever. He ate the entire bag in one sitting.";

                    using (var timeLine = new DefaultTimeline(24)) {
                        var vidGroup1 = timeLine.AddVideoGroup("videoGroup1", 24, 24, txtImg.Properties.Size.Width, txtImg.Properties.Size.Height);
                        var vidTrack1 = vidGroup1.AddTrack();

                        var audioGroup = timeLine.AddAudioGroup("audioGroup1", 24);
                        var audioTrack1 = audioGroup.AddTrack();

                        var audioFileName = await txtSpeech.SynthesizeSpeechAsync(text);
                        var audioLen = TimelineBuilder.ToSeconds(MediaInspector.GetLength(audioFileName));

                        var audioClip = audioTrack1.AddAudio(audioFileName, 0, audioLen);

                        var imgFileName = await txtImg.RenderImageAsync(text);
                        vidTrack1.AddImage(imgFileName, InsertPosition.Absolute, 0, 0, audioLen);

                        _renderer = new WindowsMediaRenderer(timeLine, "output.wmv", WindowsMediaProfiles.HighQualityVideo);

                        _renderer.RenderCompleted += _renderer_RenderCompleted;

                        _renderer.Render();
                    }

        private void _renderer_RenderCompleted(object sender, EventArgs e) {
            Process.Start("output.wmv");
        }

The said problem exists still but, now the end time of the video is missing.

Tayab
  • 311
  • 2
  • 13
  • You call `BeginRender()`, and then the timeline gets disposed. What happens if you call `Render()` instead? – CodeCaster Aug 28 '19 at 17:27
  • @CodeCaster see post edit :/ – Tayab Aug 28 '19 at 17:50
  • So is the reported length for your audio file correct? – CodeCaster Aug 28 '19 at 17:52
  • @CodeCaster I logged the 'audioLen' variable and it was '11.102'. I right-clicked on the audio file, in the details tab it shows 11 seconds. However, when I play the audio file in WMP, it shows a length of 14 seconds. 14 seconds in VLC as well when opened. – Tayab Aug 28 '19 at 17:57
  • Did it yet again with different audio. 1 second difference. – Tayab Aug 28 '19 at 17:59
  • So `TimelineBuilder.ToSeconds(MediaInspector.GetLength(audioFileName))` returns the wrong value. Is this a known bug of the library? It doesn't appear to be maintained anyway. Can you work around it by, should that be the cause, not using VBR encoding, for example? – CodeCaster Aug 28 '19 at 18:03
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/198602/discussion-between-tayab-and-codecaster). – Tayab Aug 28 '19 at 18:08

1 Answers1

1

Thanks to @CodeCaster 's help I finally ended up with a solution.

I was so desperate to try and make everything work with just the Splicer library, and keeping the dependencies in my program to a minimum.

However, I ended up using the NAudio library which gives the correct length of my audio clips. I had to change my audio export from MPEG to MP3, of course.

Here's the article where I found the solution: [Click]

Here's some modified code:

                    var mp3FileReader = new Mp3FileReader(audioFileName);
                    //var audioLen = TimelineBuilder.ToSeconds(MediaInspector.GetLength(audioFileName));
                    var audioLen = mp3FileReader.TotalTime.TotalSeconds;

Lesson that I learned:

If you trust external code too much, you might overlook any problems that it might cause. And instead doubt yourself.

Tayab
  • 311
  • 2
  • 13