mpv-player / mpv

🎥 Command line video player
https://mpv.io
Other
28.09k stars 2.88k forks source link

playback lagging when watching stream for long time #5419

Open lpaseen opened 6 years ago

lpaseen commented 6 years ago

mpv version and platform

Fedora 27, stock mpv version - mpv-0.27.0-1.fc27.x86_64

Reproduction steps

Start streaming a webcam and note the lag. Sample of my command pointing to a public camera (with a not that correct time) mpv --no-cache --aid=no 'http://216.168.105.248:12122/mjpg/video.mjpg' Note the lag between the time shown in the stream and current time. At home over local network it lags 3-5 seconds at the beginning. Leave it running for a day or more now the lag is closer to a minute or more

Expected behavior

A few seconds delay constant over time.

Actual behavior

The lag slowly increases over time, close to a minute after a day. Only way to resync seems to be restart the stream.

Log file

sprunge.us gave error 500 so I put a log on https://pastebin.com/9KDX25Dz

Sample files

Sample files needed to reproduce this issue can be uploaded to https://0x0.st/ or similar sites. (Only needed if the issue cannot be reproduced without it.) Do not use garbage like "cloud storage", especially not Google Drive.

kevmitch commented 6 years ago

This still happens with 2018.01.13.a5f53da229. You can see from the OSC seek bar that more "future" becomes seekable over time. If this is a live stream, there's only one way that can happen.

At first I thought this might have to do with video-sync slowing down the playback speed, but the same thing happens with all of --no-config --no-config --video-sync=desync --no-config --video-sync=display-vdrop

ghost commented 6 years ago

In general, live streams will always desync, because mpv has no way to adjust playback to some remote reference clock or something. And raw mjpeg streams have no such mechanism anyway. So if mpv's clock is even just slightly slower than the camera's, it will always get behind in time. (Maybe we should have some sort of live mode, which speeds up playback a bit if the buffered amount becomes too high.)

In addition and in this specific case, FFmpeg will assume some random FPS (apparently 25 fps), which could be wrong. mjpeg has no timestamps, but FFmpeg adds them, which makes mpv print a confusing message. You can try playing with --no-correct-pts --fps=23.976. The former tells it to ignore timestamps (which in this case are just FFmpeg's made up garbage), the latter tells it what framerate to assume.

ghost commented 6 years ago

Also the stream appears to have just gone offline, which means no more testing for me.

lpaseen commented 6 years ago

Tried adding --no-correct-pts --fps=23.976 and that makes it behave strange. The timestamp from the stream stops, then after 10 sec or so it quickly speed up until it's just 2 sec behind, stops for 10 sec, speed up again... I been using totem and that seems to be stable, can have it running for two-three days without issue. I checked FPS there and it stated 10 so I started mpv with --fps=10 and at least it's now updating seconds properly, about 3-4 sec behind which I find ok. 4h later it is still 3-4sec behind so it might work by hardcoding the fps. I wonder how totem does it if it's no info in the stream.

ghost commented 6 years ago

For such a stream you could try --untimed (requires --video-sync=audio).

alok0 commented 6 years ago

This might not be related, but sounds similar, for an internet stream (lets say a live hls stream), if for whatever reason it takes extra long to get the latest hls segment, either due to something on the broadcaster's end, or something between my computer and the cdn, this will add delay for as much time is wasted trying to get that segment. So if it took an extra 2 seconds to download that segment, now mpv has added 2 seconds of latency to the live stream.

Assuming that the cache level is an indicator for how far behind "live" it is for live streams, ideally I'd like a mode that either automatically adjusts the playback speed to maintain a certain cache level, or a mode that skips ahead if the cache ever grows past a certain threshold.

For now, some streams i've used --speed=1.005 as a work around, but that means every so often it will cache underflow and cause some buffering.

francisuk1989 commented 6 years ago

@kevmitch referencing this issue https://github.com/mpv-player/mpv/issues/5564 just thought ill let you know that i just basically done (but for an Foscam H.264 camera)

mpv --record-file BackDoorCamera.mkv rtsp://user:pass@192.168.0.252/11

it displays fine when is recording but soon as i go to playback the file is all speeded up say x10 times the normal speed, even tried both mkv and ts

however http://216.168.105.248:12122/mjpg/video.mjpg is an motion-JPEG and the source comes from an Axis camera what may have different outcomes.

Edit have done a little test on the Axis Public camera http://216.168.105.248:12122/mjpg/video.mjpg and the playback file from mpv recording works and plays fine see example file https://u.teknik.io/COatf.mkv

Im also using mc3man's PPA on Ubuntu 16.04.3 x64 via https://launchpad.net/~mc3man/+archive/ubuntu/mpv-tests

mpv --record-file AxisPublic1.mkv http://216.168.105.248:12122/mjpg/video.mjpg

Playing: http://216.168.105.248:12122/mjpg/video.mjpg

[lavf] This format is marked by FFmpeg as having no timestamps! [lavf] FFmpeg will likely make up its own broken timestamps. For [lavf] video streams you can correct this with: [lavf] --no-correct-pts --fps=VALUE [lavf] with VALUE being the real framerate of the stream. You can [lavf] expect seeking and buffering estimation to be generally [lavf] broken as well. (+) Video --vid=1 (mjpeg 752x480) [recorder] This is an experimental feature. Output files might be broken or not play correctly with various players (including mpv itself). VO: [gpu] 752x480 => 752x528 yuv420p V: 00:00:26 / 00:00:33 (80%) Cache: 6s+8MB

mpv --version mpv git-2018-02-01-7f3c710-dirty Copyright © 2000-2018 mpv/MPlayer/mplayer2 projects built on Thu Feb 22 12:49:39 UTC 2018 ffmpeg library versions: libavutil 56.7.100 libavcodec 58.9.100 libavformat 58.7.100 libswscale 5.0.101 libavfilter 7.11.101 libswresample 3.0.101 ffmpeg version: git-2018-02-01-b1af0e2

lpaseen commented 6 years ago

have now tried a few combinations, starting with "mpv --no-config --no-cache --no-correct-pts --untimed --video-sync=audio --mute=yes" I also tried without --no-correct-pts or --untimed or both but it works just as good/bad as --fps=10, will always loose sync after some time. Some combinations made it jumpy, looking at the time in the stream it kind of hangs for a few seconds then quickly catch up (it shows something like 10 seconds in one second), then hangs again. I don't know what totem is doing but I just start the steam with "totem --mute rtsp://...." and it keep sync. Before you ask "why don't I just use totem?" - I was hoping someone here can be interested enough in the issue to have it fixed in mpv because totem cost to much in regards to cpu. I have no clue what it's doing but right now streaming same stream that mpv use <25% CPU to show totem use >300% cpu! (maybe I should open a case with them for that part and see what is fixed first :) )

ghost commented 4 years ago

What rtsp implementation does totem use?

scratchboom commented 4 years ago

mpv http://host:8080/mjpeg --profile=low-latency helped me

wrybread commented 3 years ago

The -profile=low-latency works beautiful for me... for awhile. And then after a few hours it gets jerky and laggy. I was thinking a good workaround would be to queue a playlist of 1 hour chunks... Can anyone think of a way to do that? This is a network camera RTSP stream.

eddul-h commented 3 years ago

I'm currently trying to work around this issue by using a small js script that dynamically changes the playback speed to catch up if we fall behind more than .nn seconds.

The example script also tries to keep the stream running by reloading it if it seems to have stalled for whatever reason.

Add the --idle --script example.js command line options

example.js

var speed = 1.0;
var oldspeed = speed;
var time = 0;
var playing = false;
var thresh = 0.4;
var delay = 0;
var path;

function on_time_rem() {
    delay = mp.get_property('time-remaining');

    if(delay>thresh) {
        speed = 1+(delay-thresh);
        //mp.log('info', 'Lagging behind: ' + delay+ ' (speed: ' + speed + ')');
    } else {
        speed = 1.0;
    }

    if(speed != oldspeed)
        mp.set_property('speed', speed);

    oldspeed = speed;
}

function stall_check() {
    //mp.log('info', 'Running stall_check');

    if(!playing) {
        return;
    }

    path = mp.get_property('path');

    var pt = mp.get_property('playback-time');

    if(!pt || (time && time == pt)) {
        //stalled
        playing = false;
        mp.log('info', 'Stalled at: ' + pt);
        mp.command('stop');
        mp.command('playlist-clear');
    }

    time = pt;
}

function file_loaded() {
    playing = true;
}

function reload_stream() {
    //mp.log('info', 'Are we playing? ' + playing);

    if(!playing) {
        mp.log('info', 'Reloading ' + path);
        mp.command('loadfile ' + path);
    }
}

mp.register_event("file-loaded", file_loaded)

var laggingInterval = setInterval(on_time_rem, 100);
var stallInterval = setInterval(stall_check, 2000);
var reloadInterval = setInterval(reload_stream, 5000);
thw26 commented 5 months ago

I stumbled upon this issue while looking for a solution. I've found that much audio is what causes my Reolink cameras' RTMP streams to slow down. Watching the cameras' FLV stream with their built-in web browser may at times jump, but it is pretty constant.

I am currently testing the following command but it seems to be working.

mpv --audio-buffer=0.8 --video-sync=audio --untimed --profile=low-latency --no-cache $URL

I have tried adding --no-correct-pts and I've tried changing the profile to fast. So far this has been pretty good. If one of the streams slows down, eventually it plays "catch up". I'd have to do more testing on audio to see what happens.