Zibbp / ganymede

Twitch VOD and Live Stream archiving platform. Includes a rendered and real-time chat for each archive.
https://github.com/Zibbp/ganymede
GNU General Public License v3.0
491 stars 25 forks source link

Live archive sound high pitched and video desync #492

Closed Blaiz0 closed 2 months ago

Blaiz0 commented 2 months ago

I have been using ganymede for a while, first on a weak NAS, then a windows machine because it had more processing power. Got tired of running docker on windows, so yesterday I installed proxmox and fired up ubuntu VM with docker to run my containers..

While moving to the new machine I naturally upgraded to v3.0.1 Started with a new docker compose file, and no config file. Only copied the ganymede database to a local folder, and mounted the vods folder from the nas with smb. Tested archiving a live stream last night, for 30 min, no issues at all!

Today there was a 6.5 hour stream, and in the ganymede player the sound is slightly high pitched and gets out of sync with the video. If i play the same mp4 file with a local video player, the sound seems to stay synced when skipping around, but is still high pitched. Almost seems like its running at x1.1 speed. Streamer sounds like Mickey Mouse.

In the logfiles there is a warning about "Non-Monotonous DTS in Output Stream", suspect this might be the reason for the issues. But I don't know what is causing it, if its related to the new config, OS, virtualization, or the upgrade to 3.0.

Edit: Did some further investigation and a few other streams I archived after the upgrade also has the same error, its just not noticeable when watching the video.

Also noticed that streamlink detected an ad in the start of the stream, the first 10 sec of the vod there is the twitch window with "preparing your stream". Shouldn't be any ads on this channel. Added auth-token during setup. ffmpeg and streamlink arguments are left default: -c:v copy -c:a copy --twitch-low-latency,--twitch-disable-hosting

FFprobe for the vod ``` { "format": { "bit_rate": "5180649", "duration": "23550.598000", "filename": "/data/videos/"LiveStreamer"/2024-08-23-42782149848-live-b2edbeac-6148-11ef-9c89-0242ac120006/42782149848-video.mp4", "format_long_name": "QuickTime / MOV", "format_name": "mov,mp4,m4a,3gp,3g2,mj2", "nb_programs": 0, "nb_streams": 2, "probe_score": 100, "size": "15250924723", "start_time": "0.000000", "tags": { "compatible_brands": "isomiso2avc1mp41", "encoder": "Lavf59.27.100", "major_brand": "isom", "minor_version": "512" } }, "streams": [ { "avg_frame_rate": "386212735/6442341", "bit_rate": "5000110", "bits_per_raw_sample": "8", "chroma_location": "left", "closed_captions": 0, "codec_long_name": "H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10", "codec_name": "h264", "codec_tag": "0x31637661", "codec_tag_string": "avc1", "codec_type": "video", "coded_height": 1080, "coded_width": 1920, "disposition": { "attached_pic": 0, "captions": 0, "clean_effects": 0, "comment": 0, "default": 1, "dependent": 0, "descriptions": 0, "dub": 0, "forced": 0, "hearing_impaired": 0, "karaoke": 0, "lyrics": 0, "metadata": 0, "original": 0, "still_image": 0, "timed_thumbnails": 0, "visual_impaired": 0 }, "duration": "23549.582978", "duration_ts": 2119462468, "extradata_size": 40, "field_order": "progressive", "film_grain": 0, "has_b_frames": 4, "height": 1080, "id": "0x1", "index": 0, "is_avc": "true", "level": 40, "nal_length_size": "4", "nb_frames": "1411777", "pix_fmt": "yuv420p", "profile": "Main", "r_frame_rate": "30/1", "refs": 1, "start_pts": 0, "start_time": "0.000000", "tags": { "handler_name": "VideoHandler", "language": "und", "vendor_id": "[0][0][0][0]" }, "time_base": "1/90000", "width": 1920 }, { "avg_frame_rate": "0/0", "bit_rate": "160330", "bits_per_sample": 0, "channel_layout": "stereo", "channels": 2, "codec_long_name": "AAC (Advanced Audio Coding)", "codec_name": "aac", "codec_tag": "0x6134706d", "codec_tag_string": "mp4a", "codec_type": "audio", "disposition": { "attached_pic": 0, "captions": 0, "clean_effects": 0, "comment": 0, "default": 1, "dependent": 0, "descriptions": 0, "dub": 0, "forced": 0, "hearing_impaired": 0, "karaoke": 0, "lyrics": 0, "metadata": 0, "original": 0, "still_image": 0, "timed_thumbnails": 0, "visual_impaired": 0 }, "duration": "23550.586979", "duration_ts": 1130428175, "extradata_size": 2, "id": "0x2", "index": 1, "nb_frames": "1013645", "profile": "LC", "r_frame_rate": "0/0", "sample_fmt": "fltp", "sample_rate": "48000", "start_pts": 480, "start_time": "0.010000", "tags": { "handler_name": "SoundHandler", "language": "und", "vendor_id": "[0][0][0][0]" }, "time_base": "1/48000" } ] } ```

b2edbeac-6148-11ef-9c89-0242ac120006-video-convert.log

b2edbeac-6148-11ef-9c89-0242ac120006-video.log

Zibbp commented 2 months ago

The high pitched audio is due to ads in the live stream. The twitch ads are spliced into the stream at a different audio sample rate than the stream audio is. This causes issues when ffmpeg tries to copy the audio track over to the post processed file. The only true solution to this is to not have any ads which is accomplished by:

  1. Using your twitch token (need to be subscribed to the channel or have turbo)
  2. Use a stream proxy (Admin > Settings).

You have your twitch token populated in Admin > Settings? And you're either subscribed to the channel or have turbo? If so, can you post the full output from the "running streamlink" log from the API container? You will need to enable debug logging with the DEBUG=true environment variable. Be sure to blank out your twitch token, I just need to see the full command. What the log line looks like:

{"level":"debug","channel":"fl0m","cmd":"https://twitch.tv/fl0m best,best --force-progress --force --twitch-low-latency --twitch-disable-hosting -o /data/temp/44719661531_04bbff4c-61ba-11ef-b1fd-0242ac1a0006-video.mp4","time":"2024-08-23T20:41:45-05:00","message":"running streamlink"}

Another possible fix-you can try updating the "Video Convert FFmpeg Args" in Admin > Settings removing -c:a copy and replacing with -c:a aac. This will re-encode the audio stream. Reportedly this works for some streams, so maybe worth a shot?

Blaiz0 commented 2 months ago

That's interesting. I am subscribed. Never experienced it before, but I guess iv only been archiving subbed channels and successfully passed the auth token.

Was already running debug, just to see what's going on during "commissioning". The stream in question had the following log:

2024-08-23T14:10:34+02:00 DBG running streamlink | channel=*LiveStreamer* cmd=https://twitch.tv/*LiveStreamer* best,best --force-progress --force --twitch-low-latency --twitch-disable-hosting -o `/data/temp/42782149848_b2edbeac-6148-11ef-9c89-0242ac120006-video.mp4

Cant see any token to redact. I assume it should have been a "--twitch-api-header=Authorization=OAuth abcdefghijklmnopqrstuvwxyz0123" argument in here.

The token is set in [ip]:4801/admin/settings. Checked if my token is correct, it is 30 characters and the same as what is entered in settings, and no quotes. Checked the config file, and the auth token is there. Proxy is disabled and channel is not whitelisted.

Was thinking maybe the api container has to be restarted, but the wiki says it does not require it. I'll try a restart anyway and see if it helps. Edit: Yes, that did the trick 👍 Now streamlink argument includes --http-header Authorization=OAuth xxxxxxxxxxxxxxxxxxxx Should have tried it immediately, but after changing OS and using proxmox for the first time I almost assumed it was some kind of rendering error in the ffmpeg job, not auth problems.

Whats the reason for the low latency argument, does it help with chat sync?

On another note, as of streamlink 5.0.0 --twitch-disable-hosting has been removed And --force-progress should probably be replaced with --progress=force

Zibbp commented 2 months ago

I'll see if I can get the config to 'reload' without a restart. If not, I'll just put a warning on the settings page to restart the API container.

Low latency helps with the video and chat sync.