Question

I have a problem where seek method of flowplayer is not going to the exact second specified - it's goes to about 8 seconds instead of 10.

Jsfiddle Example

var $player = $('#player');
var video = flowplayer($player[0], {
    src: 'http://releases.flowplayer.org/swf/flowplayer-3.2.18.swf',
    wmode: 'opaque'
}, {
    clip: {
        autoPlay: true,
        onCuepoint: [
            [10000], // 10 Seconds
            function () {
                video.pause();
                alert('10 second Cuepoint reached');
            }]
    }
});

$('a').click(function (e) {
    e.preventDefault();
    video.seek(10);   
});

It's fairly clear to see there's a few seconds of playback after clicking the link, before the cuepoint is reached, and it can also be confirmed by checking the time in the flowplayer control bar.

Thanks in advance for any help.

Was it helpful?

Solution

In reality the behavior mentioned in your question is not a special problem of flowplayer but it's related to NetStream object and the stream itself.

To more understand, let's start by taking a look on the MetaData of the video used in your example :

avcprofile = 66
videocodecid = avc1
trackinfo = [object Object],[object Object]
avclevel = 30
duration = 25.309750566893424
width = 500
height = 300
aacaot = 2
videoframerate = 25
moovposition = 44
audiocodecid = mp4a
seekpoints = [object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
    0 = [object Object]
        time = 0
        offset = 8556
    1 = [object Object]
        time = 4
        offset = 302415
    2 = [object Object]
        time = 7.72
        offset = 687933
    3 = [object Object]
        time = 10.76
        offset = 1169520
    4 = [object Object]
        time = 13.64
        offset = 1593324
    5 = [object Object]
        time = 17.64
        offset = 2082047
    6 = [object Object]
        time = 21.64
        offset = 2434386
audiosamplerate = 44100
audiochannels = 2

Here, we will focus on seekpoints which present the keyframes of our stream (video). Sometimes, MetaData contains keyframes instead of seekpoints, and sometimes the video contains neither seekpoints nor keyframes, in this case we have to inject it to avoid playback problems, if it's possible of course.

So In our case, we have 7 keyframes :

- 1st keyframe : at 0:00
- 2nd keyframe : at 0:04
- 3rd keyframe : at 0:07.72
- 4th keyframe : at 0:10.76
- 5th keyframe : at 0:13.64
- 6th keyframe : at 0:17.64
- 7th keyframe : at 0:21.64

So when seeing the definition of NetStream.seek() :

Seeks the keyframe (also called an I-frame in the video industry) closest to the specified location. The keyframe is placed at an offset, in seconds, from the beginning of the stream.

We can understand that the NetStream object will go to the closest keyframe to the specified location or time, and we can say closest keyframe before the specified time. That's why, when you try to seek to the 10th second, the player will go directly to the keyframe at the second 7.72. Also, if you try to go to the 15th second, player will play from the keyframe at 13.64.

So how to avoid such problem ?

  • Put a keyframe every second, which acts directly on the size of the video file. To do that, you can use ffmpeg, for example, using this command :

    ffmpeg -i original_video.mp4 -force_key_frames "expr:gte(t,n_forced*1)" new_video.mp4

    of course you have to adapt the command to you encoding preset.

  • Using a streaming server, as Adobe Media Server, Wowza, Red5, ... which you can configure to avoid such problem.

  • Using a web server with a specific module to streaming video, such as H264 Streaming Module for Apache, Nginx http mp4 module, ...

Hope all that can help you.

OTHER TIPS

When Flowplayer seeks to the specified time of the current clip, it will start playing from a nearby keyframe.

The keyframe concept is described on a Flowplayer page about pseudostreaming (http://flash.flowplayer.org/plugins/streaming/pseudostreaming.html):

Keyframes are complete video frames (or images) which are inserted at a given interval into a video clip. The frames between the keyframes are 'partial' as they need other frames (reference frames) to be displayed. The interval might decrease to cater for scene changes and high motion scenes. In pseudostreaming, the user can only seek to a location where there is a complete keyframe. If you don't have enough keyframes your video is not well-suited for fine-grained seeking. With a good encoding software you can set the keyframe interval, minimum keyframe interval and the sensitivity to scene changes.

I analyzed the example video on your Jsfiddle example and it has keyframes at 0.00 s, 4.00 s, 7.72 s, 10.76 s, 13.64 s and so on. That is why your video starts at 7.72 s and not 10.00 s when you are seeking to 10 seconds.

To be able to seek to any second, you should consider adding keyframes for every second to your videos. Ffmpeg supports this with -force_key_frames (https://ffmpeg.org/ffmpeg.html).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top