Closed DrHurt closed 4 weeks ago
I have done more testing: AVPlayer -> perfectly smooth on 60Hz VLC -> smooth on 60Hz MPV -> medium stutter on 60Hz KSPlayer -> heavy stutter / unwatchable on 60Hz, BUT switch TV to 50Hz -> KSPlayer is perfectly smooth!!
Interesting Discovery: iOS AVPlayer supports .ts streams!!! containing hevc/avc and aac/ac3
If you rename http://xxx/video.ts to http://xxx/video.m3u it works perfectly with avplayer. No need to convert or encode, just change extension.
Maybe KSPlayer should use avplayer by default for ts streams (like it does with m3u currently)
我改了下代码,你用test flight包试下(Build 2.4.4 (2) )。并且把 displayLink preferredFrame 这个开关打开。看下有没有变得顺滑一点。
I did the testing using 2.4.4 (276) from test flight.
It feels like displayLink preferredFrame makes the problem slightly worse
I did the testing using 2.4.4 (276) from test flight.
It feels like displayLink preferredFrame makes the problem slightly worse
Have you tried with “ Match Frame Rate” set to ON?
https://support.apple.com/en-us/102277
If it is disabled it is normal that a PAL content would stutter on a NTSC format (60hz)
I’m well aware of the judder caused by 25 not fitting into 60 but that’s not what’s happening here. KSPlayer seems to have another bigger problem with 25fps on 60Hz where other players don’t.
I think I found the problem: It’s caused by KSPlayer “audio video sync” causing display FPS to fluctuate to stay in sync with audio
This is probably confusing my TV motion processing algorithms which causes stutter/tearing.
Can we get a test with AV sync disabled so framerate stays constant? (Or maybe force constant 25fps)
I’ll do more testing later with video without no sound track to confirm!
I’m well aware of the judder caused by 25 not fitting into 60 but that’s not what’s happening here. KSPlayer seems to have another bigger problem with 25fps on 60Hz where other players don’t.
I think I found the problem: It’s caused by KSPlayer “audio video sync” causing display FPS to fluctuate to stay in sync with audio
This is probably confusing my TV motion processing algorithms which causes stutter/tearing.
Can we get a test with AV sync disabled so framerate stays constant? (Or maybe force constant 25fps)
I’ll do more testing later with video without no sound track to confirm!
VLC and MPV does not support match rate, hence in the backend those apps multiply the number of frames to match the screen refresh rate but at a cost of reducing image quality
You will see that if you enable the toggle I shared above the image will be smooth
I’m well aware of the judder caused by 25 not fitting into 60 but that’s not what’s happening here. KSPlayer seems to have another bigger problem with 25fps on 60Hz where other players don’t.
I think I found the problem: It’s caused by KSPlayer “audio video sync” causing display FPS to fluctuate to stay in sync with audio
This is probably confusing my TV motion processing algorithms which causes stutter/tearing.
Can we get a test with AV sync disabled so framerate stays constant? (Or maybe force constant 25fps)
I’ll do more testing later with video without no sound track to confirm!
And not every stream is in 50hz, some will be in 60hz; so to have the best experience in terms of smoothness you have to enable match frame rate in the ATV settings
And, in KSplayer, this is managed by AVDisplayCriteria
But it checks first if you have enabled “dynamic range” and “frame match” in ATV settings
You are missing the point my friend and going off topic! I’m aware of everything you say!
I’m simply suggesting that there’s a bug with KSPlayer where in trying to maintain av sync, it’s causing output framerate to irregularly fluctuate which on my Philips TV causes more stutters than expected.
I’ll do more objective testing later today and share my results here. That’ll be my small contribution to this great project.
I did the testing using 2.4.4 (276) from test flight.
It feels like displayLink preferredFrame makes the problem slightly worse
@DrHurt 因为Xcode cloud打包失败了。所以我今天是本地打包的,一定要用Build 2.4.4 (2) 这个版本才可以,2.4.4 (2) 才是最新的版本,不能用2.4.4 (276) 。 你在tvos的testflight可以看到 2.4.4 (2) 吗?
I did the testing using 2.4.4 (276) from test flight. It feels like displayLink preferredFrame makes the problem slightly worse
@DrHurt 因为Xcode cloud打包失败了。所以我今天是本地打包的,一定要用Build 2.4.4 (2) 这个版本才可以,2.4.4 (2) 才是最新的版本,不能用2.4.4 (276) 。 你在tvos的testflight可以看到 2.4.4 (2) 吗?
I cannot see 2.4.4 (2) on TestFlight.
PROBLEM CONFIRMED: 25fps with audio track == stutter 25fps with NO audio track == smooth
I believe KSPlayer is changing output frame rate while trying to keep audio and video in sync.
Perhaps you could add an option to disable audio video sync correction for now.
And if a user really needs it, KSPlayer can change audio speed instead of video frame rate.
Attached are 3 files: WithAudio.mp4 == stutter NoAudio.mp4 == smooth Demo.mp4 to show how it looks on my TV (much worse in person)
Note another bug, when playing NoAudio.mp4, it shows Display FPS = 30 (which is wrong)
https://drive.google.com/file/d/1nCA67hUOk9jdsYtICuJAujf-HH2OKQEE/view?usp=sharing
I did the testing using 2.4.4 (276) from test flight. It feels like displayLink preferredFrame makes the problem slightly worse
@DrHurt 因为Xcode cloud打包失败了。所以我今天是本地打包的,一定要用Build 2.4.4 (2) 这个版本才可以,2.4.4 (2) 才是最新的版本,不能用2.4.4 (276) 。 你在tvos的testflight可以看到 2.4.4 (2) 吗?
I cannot see 2.4.4 (2) on TestFlight.
PROBLEM CONFIRMED: 25fps with audio track == stutter 25fps with NO audio track == smooth
I believe KSPlayer is changing output frame rate while trying to keep audio and video in sync.
Perhaps you could add an option to disable audio video sync correction for now.
And if a user really needs it, KSPlayer can change audio speed instead of video frame rate.
Attached are 3 files: WithAudio.mp4 == stutter NoAudio.mp4 == smooth Demo.mp4 to show how it looks on my TV (much worse in person)
Note another bug, when playing NoAudio.mp4, it shows Display FPS = 30 (which is wrong)
https://drive.google.com/file/d/1nCA67hUOk9jdsYtICuJAujf-HH2OKQEE/view?usp=sharing
@kingslay I confirm that when you play the video “WithAudio.mp4” there are stutters. It is easier to notice it when you play the video at x2 speed
@kingslay i used those settings
using displaylink preferredFrame
makes it worse
@DrHurt 你看下是否可以看到 2.4.4 (288)这个版本。可以的话,那把 displayLink preferredFrame 这个开关打开。测试下。
你看下是否可以看到 2.4.4 (288)这个版本。可以的话,那把 displayLink preferredFrame 这个开关打开。测试下。
It worked fine on my side, @DrHurt can you also try it?
@DrHurt 你看下是否可以看到 2.4.4 (288)这个版本。可以的话,那把 displayLink preferredFrame 这个开关打开。测试下。
Unfortunately not fixed here with 288
Findings so far: (First Player Type = KSPlayer in settings because this is what it uses with ts live streams)
Thinking out loud here, but I feel this 30fps bug is related. Why 30fps specifically? Is is hardcoded? Is it a stray variable somewhere in the code?
Adding the audio track slows it down to 25fps. Is KSPlayer is trying to slow down the video to match audio causing stuttering? Maybe if this is fixed, it will fix the stuttering?
Attached are 2 more files as an example. Look at the scrolling news ticker at the bottom. https://drive.google.com/file/d/166brl9R6E47-PYnX2inHppkWQcuo_gLb/view?usp=sharing
@DrHurt 视频的展示需要等待音频,这样才不会有音视频不一致的问题。我用你给的SkyNoAudio 和SkyWithAudio 在preferredFrame 开启的情况下。日志显示每个视频帧显示的间隔是很平均的。所以应该是顺畅的。 @cdguy 麻烦你也试下这两个视频。看下会不会顺畅。 warning KSPlayer: MEPlayerItem.swift:1048 setVideo(time:position:) | [video] video interval 0.03978395834565163 video diff 0.03999999999999915 warning KSPlayer: MEPlayerItem.swift:1048 setVideo(time:position:) | [video] video interval 0.03979429160244763 video diff 0.040000000000000924 warning KSPlayer: MEPlayerItem.swift:1048 setVideo(time:position:) | [video] video interval 0.03973166667856276 video diff 0.03999999999999915 warning KSPlayer: MEPlayerItem.swift:1048 setVideo(time:position:) | [video] video interval 0.04018949996680021 video diff 0.040000000000000924 warning KSPlayer: MEPlayerItem.swift:1048 setVideo(time:position:) | [video] video interval 0.039325833320617676 video diff 0.03999999999999915 warning KSPlayer: MEPlayerItem.swift:1048 setVideo(time:position:) | [video] video interval 0.03990291664376855 video diff 0.040000000000000924 warning KSPlayer: MEPlayerItem.swift:1048 setVideo(time:position:) | [video] video interval 0.039741375017911196 video diff 0.03999999999999915 warning KSPlayer: MEPlayerItem.swift:1048 setVideo(time:position:) | [video] video interval 0.03982249996624887 video diff 0.040000000000000924 warning KSPlayer: MEPlayerItem.swift:1048 setVideo(time:position:) | [video] video interval 0.03976383316330612 video diff 0.03999999999999915 warning KSPlayer: MEPlayerItem.swift:1048 setVideo(time:position:) | [video] video interval 0.039663333212956786 video diff 0.040000000000000924 warning KSPlayer: MEPlayerItem.swift:1048 setVideo(time:position:) | [video] video interval 0.03983716666698456 video diff 0.03999999999999915 warning KSPlayer: MEPlayerItem.swift:1048 setVideo(time:position:) | [video] video interval 0.03975879168137908 video diff 0.040000000000000924 warning KSPlayer: MEPlayerItem.swift:1048 setVideo(time:position:) | [video] video interval 0.03968283347785473 video diff 0.03999999999999915 warning KSPlayer: MEPlayerItem.swift:1048 setVideo(time:position:) | [video] video interval 0.03993795835413039 video diff 0.040000000000000924 warning KSPlayer: MEPlayerItem.swift:1048 setVideo(time:position:) | [video] video interval 0.03973370813764632 video diff 0.03999999999999915 warning KSPlayer: MEPlayerItem.swift:1048 setVideo(time:position:) | [video] video interval 0.03972462494857609 video diff 0.040000000000000924 warning KSPlayer: MEPlayerItem.swift:1048 setVideo(time:position:) | [video] video interval 0.03987420839257538 video diff 0.03999999999999915 warning KSPlayer: MEPlayerItem.swift:1048 setVideo(time:position:) | [video] video interval 0.03972887503914535 video diff 0.040000000000000924 warning KSPlayer: MEPlayerItem.swift:1048 setVideo(time:position:) | [video] video interval 0.039944166550412774 video diff 0.03999999999999915 warning KSPlayer: MEPlayerItem.swift:1048 setVideo(time:position:) | [video] video interval 0.0395286250859499 video diff 0.040000000000000924 warning KSPlayer: MEPlayerItem.swift:1048 setVideo(time:position:) | [video] video interval 0.039920249953866005 video diff 0.03999999999999915 warning KSPlayer: MEPlayerItem.swift:1048 setVideo(time:position:) | [video] video interval 0.03995670843869448 video diff 0.040000000000000924 warning KSPlayer: MEPlayerItem.swift:1048 setVideo(time:position:) | [video] video interval 0.03965212497860193 video diff 0.03999999999999915 warning KSPlayer: MEPlayerItem.swift:1048 setVideo(time:position:) | [video] video interval 0.03970375005155802 video diff 0.03999999999999915 warning KSPlayer: MEPlayerItem.swift:1048 setVideo(time:position:) | [video] video interval 0.03968204162083566 video diff 0.040000000000000924 warning KSPlayer: MEPlayerItem.swift:1048 setVideo(time:position:) | [video] video interval 0.039921333314850926 video diff 0.03999999999999915 warning KSPlayer: MEPlayerItem.swift:1048 setVideo(time:position:) | [video] video interval 0.039765708381310105 video diff 0.040000000000000924 warning KSPlayer: MEPlayerItem.swift:1048 setVideo(time:position:) | [video] video interval 0.03977945842780173 video diff 0.03999999999999915 warning KSPlayer: MEPlayerItem.swift:1048 setVideo(time:position:) | [video] video interval 0.039889583364129066 video diff 0.040000000000000924 warning KSPlayer: MEPlayerItem.swift:1048 setVideo(time:position:) | [video] video interval 0.03953749989159405 video diff 0.03999999999999915 warning KSPlayer: MEPlayerItem.swift:1048 setVideo(time:position:) | [video] video interval 0.03988879150711 video diff 0.040000000000000924 warning KSPlayer: MEPlayerItem.swift:1048 setVideo(time:position:) | [video] video interval 0.03977916669100523 video diff 0.03999999999999915 warning KSPlayer: MEPlayerItem.swift:1048 setVideo(time:position:) | [video] video interval 0.03986370819620788 video diff 0.040000000000000924 warning KSPlayer: MEPlayerItem.swift:1048 setVideo(time:position:) | [video] video interval 0.03978712507523596 video diff 0.03999999999999915 warning KSPlayer: MEPlayerItem.swift:1048 setVideo(time:position:) | [video] video interval 0.039719375083222985 video diff 0.040000000000000924 warning KSPlayer: MEPlayerItem.swift:1048 setVideo(time:position:) | [video] video interval 0.039674000116065145 video diff 0.03999999999999915 warning KSPlayer: MEPlayerItem.swift:1048 setVideo(time:position:) | [video] video interval 0.039698250126093626 video diff 0.040000000000000924 warning KSPlayer: MEPlayerItem.swift:1048 setVideo(time:position:) | [video] video interval 0.0398119583260268 video diff 0.03999999999999915
But why is SkyNoAudio playing at 30fps with KSPlayer? Changing First Player Type = AVPlayer it plays normally at 25fps and smoothly.
It's smooth for cdguy because he has his TV set to 50Hz, while I have mine at 60Hz (smoother UI).
@DrHurt 视频的展示需要等待音频,这样才不会有音视频不一致的问题。我用你给的SkyNoAudio 和SkyWithAudio 在preferredFrame 开启的情况下。日志显示每个视频帧显示的间隔是很平均的。所以应该是顺畅的。 @cdguy 麻烦你也试下这两个视频。看下会不会顺畅。
@kingslay as I said, yesterday I tried both videos and your fix fixed the stutters on tvos. As we spoke yesterday, I know you are trying to find a fix for ios.
my tv settings were (via appleTV settings): 4K HDR 50hz + Dynamic Range ON + Frame Matching ON I also turned off all picture correction features such as “motion plus” etc
But why is SkyNoAudio playing at 30fps with KSPlayer? Changing First Player Type = AVPlayer it plays normally at 25fps and smoothly.
It's smooth for cdguy because he has his TV set to 50Hz, while I have mine at 60Hz (smoother UI).
There is something wrong with your setup. When I set the ATV to 60hz with FPS matching ON it is smooth
also the “without audio” track plays at 50hz, as it should be
@cdguy I’m talking about KSPlayer not the actual TV refresh rate.
I think I’ve narrowed it down even further.
Try the following: 1- TV set to 60Hz, match frame rate and dynamic range to off. 2- Play SkyNoAudio and press the i (information) and see track info will say 25fps but “Display FPS” will say ~30 and video will play quickly 3- Change TV to 50Hz and do the same, Display FPS will change to ~25 and video will play at normal speed.
So the bug seems to be that KSPlayer will decode the video at a rate equal to half the display Hz.
See screenshot playing 25fps on 60Hz and note the “Display FPS” at the bottom.
@DrHurt 当你的tvOS是只是为60hz的话,那需要把 match frame rate and dynamic range 打开,这样才能顺畅的播放25fps。我测试了不用打开 displayLink preferredFrame. 也是可以顺畅的。并且display fps也是显示为25.
所以重点是一定要打开 match frame rate and dynamic range
你们的tvOS正常会开启 match frame rate and dynamic range吗?
我也会看下 为什么 SkyNoAudio播放, display fps什么会显示为30. 确实应该是25.
我也会看下 为什么 SkyNoAudio播放, display fps什么会显示为30. 确实应该是25.
Thank you for the new testflight app It is fixed now
@DrHurt 你可以试下最新的test flight包, 目前SkyNoAudio 在tvOS 和iOS 上,不管如何设置,都可以让display fps 可以显示为25fps了。但是播放还是无法非常流畅,除非在tvOS上开启 match frame rate and dynamic range
@DrHurt 你可以试下最新的test flight包, 目前SkyNoAudio 在tvOS 和iOS 上,不管如何设置,都可以让display fps 可以显示为25fps了。但是播放还是无法非常流畅,除非在tvOS上开启 match frame rate and dynamic range
partially fixed: SkyNoAudio - smooth, playing at correct speed now (25fps on 60Hz) SkyWithAudio - stutter
displayLink preferredFrame makes everything worse so I have disable it.
Narrowing it down even further:
Definitely getting closer 👍
@DrHurt 你可以试下最新的test flight包, 目前SkyNoAudio 在tvOS 和iOS 上,不管如何设置,都可以让display fps 可以显示为25fps了。但是播放还是无法非常流畅,除非在tvOS上开启 match frame rate and dynamic range
partially fixed: SkyNoAudio - smooth, playing at correct speed now (25fps on 60Hz) SkyWithAudio - stutter
displayLink preferredFrame makes everything worse so I have disable it.
Narrowing it down even further:
- Audio set to AudioUnit - SkyWithAudio == smooth (FINALLY!)
- Audio set to (default) AVAudioEngine SkyWithAudio == stutter
Definitely getting closer 👍
Have you tried with AudioRenderer? This is the only audio decoder that supports spatial audio on tvos @DrHurt
@DrHurt 我刚增加了一个开关 Enable audio VideoClock Sync。 你用最新的test flight包2.4.6 (291) 试下
The latest version on TestFlight is 2.4.4 (289)
I will wait for the new version and let you know.
@DrHurt 我刚增加了一个开关 Enable audio VideoClock Sync。 你用最新的test flight包2.4.6 (291) 试下
Tested now and videos are PERFECTLY SMOOTH with all audio engines 👍 And videos load much more quickly now.
As to be expected, audio video sync has been a bit erratic, but at least we now know the root of the problem.
With TV speakers: videos are smooth with all audio engines. AVAudioEngine causes some video sync problems, other engines seem acceptable.
With HomePod as speaker: all audio engines seem to struggle with video sync. AVSampleBufferAudioRenderer doesn't work with live streams when connected to HomePod so couldn't test (keeps buffering). Can that be fixed? It works perfectly with mp4 for some reason.
I'll do more testing tomorrow, but significant progress here!!
@kingslay @DrHurt I tried the video file “NoAudio.mp4” using the latest beta https://drive.google.com/file/d/1nCA67hUOk9jdsYtICuJAujf-HH2OKQEE/view?usp=sharing
On ios and ipados, if I use AudioUnit, there are no stutters, however when I use AudioRenderer there are stutters both on ios and ipados.
AudioRenderer is a must in Ksplayer because it uses the latest audio libraries of Apple and it has a better management of Spatial Audio
@kingslay I did more testing today:
audio VideClock Sync == off Videos are super smooth but as expected videos randomly go out of sync with audio. This is particularly bad with HomePods causing 2-3 second lag so it not useable for me. This happens with all engines but AVAudioEngine seems to be the worst.
audio VideoClock Sync == on Videos stutter ONLY with AVAudioEngine. Video smooth with all other audio engines 👍
My suggestion: Until this AVAudioEngine sync bug is fixed, change the default audio engine in KSPlayer from AVAudioEngine to AudioUnit so that IPTV apps using KSPlayer would benefit from the improved 25fps playback. I have tested this with 25fps on 60Hz and HomePods and with 5.1 audio and everything works well.
@cdguy All the audio engines support multichannel in my limited testing but none support Atmos metadata. If you want proper atmos, you need to change First Player Type to AVPlayer (iOS native player) and use mp4 with the correct metadata. That's the only way to get my speakers to light up the "Atmos" indicator.
@DrHurt 我刚增加了一个开关 Enable audio VideoClock Sync。 你用最新的test flight包2.4.6 (291) 试下
Tested now and videos are PERFECTLY SMOOTH with all audio engines 👍 And videos load much more quickly now.
As to be expected, audio video sync has been a bit erratic, but at least we now know the root of the problem.
With TV speakers: videos are smooth with all audio engines. AVAudioEngine causes some video sync problems, other engines seem acceptable.
With HomePod as speaker: all audio engines seem to struggle with video sync. AVSampleBufferAudioRenderer doesn't work with live streams when connected to HomePod so couldn't test (keeps buffering). Can that be fixed? It works perfectly with mp4 for some reason.
I'll do more testing tomorrow, but significant progress here!!
@DrHurt 我刚更新了test flight包。解决了audio VideClock Sync == off 时,音频和视频不同步的问题。麻烦你试下。我也把默认的音频输出改成是AudioUnit了。我接下来会看下 AVAudioEngine ,AVSampleBufferAudioRenderer的问题
我刚更新了test flight包。解决了audio VideClock Sync == off 时,音频和视频不同步的问题。麻烦你试下。我也把默认的音频输出改成是AudioUnit了。我接下来会看下 AVAudioEngine ,AVSampleBufferAudioRenderer的问题
ALL FIXED 👍 👍 👍 audio VideClock Sync == off && AudioUnit --> smooth video, perfect sync (even with HomePods)
I think these should be the default settings now so IPTV apps can use them by default. (At the moment default is sync on)
Congratulations Kingslay
You can close this thead @kingslay
So, to be clear... right now what are the suggested settings for the audio engine and the videoClock sync?
So, to be clear... right now what are the suggested settings for the audio engine and the videoClock sync?
AudioUnit or AudioRenderer + VideoClockSync ON
So, to be clear... right now what are the suggested settings for the audio engine and the videoClock sync?
AudioUnit or AudioRenderer + VideoClockSync ON
Thanks. And about displayLink preferredFrame? (Btw, what exactly foes this option?)
So, to be clear... right now what are the suggested settings for the audio engine and the videoClock sync?
AudioUnit or AudioRenderer + VideoClockSync ON
Thanks. And about displayLink preferredFrame? (Btw, what exactly foes this option?)
Are you asking on behalf of a dev? 😊 you can try yourself
I don’t think there’s any formal recommendation. But VideoClockSync & displayLink preferredFrame can cause stutter if display refresh rate does not equal video frame rate so I have them both off on my setup
So, to be clear... right now what are the suggested settings for the audio engine and the videoClock sync?
AudioUnit or AudioRenderer + VideoClockSync ON
Thanks. And about displayLink preferredFrame? (Btw, what exactly foes this option?)
Are you asking on behalf of a dev? 😊 you can try yourself
Not at all. Just a curious user 😅 (actually been commenting in this repo since a loooong time ago)
I understand many things about this, but I'm not a dev myself. That's why I ask... I wish I know how to develop an app lol
因为设备有很多种情况,所以目前没有一种配置完全适用于各种设备,所以我做成了各种开关。每个人可以根据自己的情况去配置参数。但是我会尽量把各个开关的默认值设置为适用于大部份设备。但是想要追求最好效果的话,那就需要去尝试各种开关。调制出最适合自己的配置。
I think this thread can be closed now. Thanks for the fixes @kingslay.
Looking forward to seeing the updates integrated into IPTV apps. I see the source hasn't been updated yet.
Test link: (25fps live stream) https://live-hls-web-aje-fa.getaj.net/AJE/01.m3u8
Playing Al Jazeera on Apple TV connected to Philips TV running at 60Hz results in stutter. Very obvious looking at the scrolling news ticker at the bottom.
Problem ONLY with ksplayer. Changing to AVPlayer WORKS perfect! Alternatively changing TV to 50Hz WORKS perfect. Also playing 24fps/30fps/60fps WORKS perfect.
I tried enabling/disabling of Asynchronous Decompression, Use DisplayLayer, Enable displayLink preferredFrame.
I suspect the problem is related to synchronising frame drawing by ksplayer to TV drawing (CADisplayLink problem?) when playing 25fps.
I'm sure all of us European users will be very happy if you fix this!
Thank you