modestimpala / OdinOnDemand

A mediaplayer mod for Valheim using SoundcloudExplode and YoutubeExplode
https://valheim.thunderstore.io/package/ValMedia/OdinOnDemand/
GNU Affero General Public License v3.0
1 stars 0 forks source link

YouTube player doesn't work, local file does #29

Open UplinkPhobia opened 2 months ago

UplinkPhobia commented 2 months ago

On launching a game, an error pops up in the console and no audio/video from YouTube can be played. Local files seem to work fine. The bug occurs on linux (manjaro), the windows version of the game seems to work fine (even on the same linux-hosted server, the windows client works but the linux one doesn't play the videos). Happens even on a minimal version of the game with only this mod and dependencies. No other error messages related to the mod are in the log.

[Error  : Unity Log] NullReferenceException: Object reference not set to an instance of an object
Stack trace:
OdinOnDemand.MPlayer.BasePlayer+<YoutubeNodeQuery>d__146.MoveNext () (at <88f056d3892f4267b61c97212708dde7>:0)
UnityEngine.SetupCoroutine.InvokeMoveNext (System.Collections.IEnumerator enumerator, System.IntPtr returnValueAddress) (at <3aefadeb43334fcf8b7b268355c16be2>:0)
UnityEngine.MonoBehaviour:StartCoroutine(IEnumerator)
OdinOnDemand.MPlayer.BasePlayer:PlayYoutube(String)
OdinOnDemand.MPlayer.BasePlayer:RPC_SetURL(String, Boolean, Single)
OdinOnDemand.MPlayer.BasePlayer:<LoadZDO>b__153_1()
OdinOnDemand.MPlayer.<DelayedExecution>d__156:MoveNext()
UnityEngine.SetupCoroutine:InvokeMoveNext(IEnumerator, IntPtr)
Stonedprophet commented 1 month ago

Same issue here.

[Error :OdinOnDemand.Utils.Net.Explode.Async+d0`1[[YoutubeExplode.Videos.Streams.StreamManifest, YoutubeExplode, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]]] Exception caught in ExecuteSafeAsync: System.Net.Http.HttpRequestException: 403 (Forbidden) at System.Net.Http.HttpResponseMessage.EnsureSuccessStatusCode () [0x0002a] in <7b507295b5354781b67be2847e846b81>:0 at YoutubeExplode.Videos.Streams.StreamClient.TryGetContentLengthAsync (YoutubeExplode.Bridge.IStreamData streamData, System.String url, System.Threading.CancellationToken cancellationToken) [0x00117] in <1508ea30d4f84f1098963a2ce6c48e4f>:0 at YoutubeExplode.Videos.Streams.StreamClient+d6.MoveNext () [0x00265] in <1508ea30d4f84f1098963a2ce6c48e4f>:0 at System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore1[TResult].GetResult (System.Int16 token) [0x0001f] in <49e424219c4a4763a398a5192b431d03>:0 at YoutubeExplode.Videos.Streams.StreamClient+<GetStreamInfosAsync>d__6.System.Threading.Tasks.Sources.IValueTaskSource<System.Boolean>.GetResult (System.Int16 token) [0x00000] in <1508ea30d4f84f1098963a2ce6c48e4f>:0 at YoutubeExplode.Utils.Extensions.AsyncCollectionExtensions.ToListAsync[T] (System.Collections.Generic.IAsyncEnumerable1[T] source) [0x000e9] in <1508ea30d4f84f1098963a2ce6c48e4f>:0 at YoutubeExplode.Utils.Extensions.AsyncCollectionExtensions.ToListAsync[T] (System.Collections.Generic.IAsyncEnumerable1[T] source) [0x001a7] in <1508ea30d4f84f1098963a2ce6c48e4f>:0 at YoutubeExplode.Videos.Streams.StreamClient.GetStreamInfosAsync (YoutubeExplode.Videos.VideoId videoId, YoutubeExplode.Bridge.PlayerResponse playerResponse, System.Threading.CancellationToken cancellationToken) [0x00124] in <1508ea30d4f84f1098963a2ce6c48e4f>:0 at YoutubeExplode.Videos.Streams.StreamClient.GetStreamInfosAsync (YoutubeExplode.Videos.VideoId videoId, System.Threading.CancellationToken cancellationToken) [0x00337] in <1508ea30d4f84f1098963a2ce6c48e4f>:0 at YoutubeExplode.Videos.Streams.StreamClient.GetManifestAsync (YoutubeExplode.Videos.VideoId videoId, System.Threading.CancellationToken cancellationToken) [0x00092] in <1508ea30d4f84f1098963a2ce6c48e4f>:0 at OdinOnDemand.Utils.Net.Explode.Async+<>c__DisplayClass1_0.<GetYoutubeManifestAsync>b__0 (System.Threading.CancellationToken cancellationToken) [0x00091] in <88f056d3892f4267b61c97212708dde7>:0 at OdinOnDemand.Utils.Net.Explode.Async.ExecuteSafeAsync[T] (System.Func2[T,TResult] operation, System.Threading.CancellationToken token) [0x0007b] in <88f056d3892f4267b61c97212708dde7>:0 [Error :OdinOnDemand.Utils.Net.Explode.URLGrab+d__16] Failed to get video manifest, check for exceptions [Warning:OdinOnDemand.MPlayer.BasePlayer] Failed to load video

Stonedprophet commented 1 month ago

Also, I noticed the CFG file is empty?

modestimpala commented 1 month ago

Well @UplinkPhobia @Stonedprophet, I have some bad news.

After looking into this I've discovered that YouTube is really cracking down on Bots and changing their API massively.

See https://github.com/Tyrrrz/YoutubeExplode/issues/794 and https://github.com/Tyrrrz/YoutubeExplode/releases/tag/6.4.2

YoutubeExplode 6.4.2 release notes state that "Due to the recent changes by YouTube, muxed streams are no longer provided. " - This mod only uses muxed streams. Even my website, https://dlp.lol/ is broken right now - and it uses an entirely different library called youtube-dlp.

I'm afraid to say it but this may be the end of Youtube integration in OdinOnDemand. Unless I somehow add cookie support, but apparently according to https://github.com/ytdl-org/youtube-dl/issues/32905#issuecomment-2308380577 cookies probably won't work for long if they even work at all. So not sure what direction to go here.

I still use youtube-dlp locally and it seems to work fine, so I might be able to switch over to that... but if muxed streams are gone entirely then we're in for a bad show.

That's all I really have for you folks right now. Sorry for the bad news, I wish Youtube would be more supportive, but ultimately they do not and never have wanted to support services like third party extractors so I am doubtful for the future.

modestimpala commented 1 week ago

So it turns out YoutubeExplode is slightly misleading as there are still low-quality muxed streams available from Youtube. To access these I've implemented YoutubeDLSharp to cover for YoutubeExplode where it falls short. See https://github.com/modestimpala/OdinOnDemand/commit/08c95cd4e576a600c3ca5fcdc4706d1d1f3e2e04 As a side effect, you can now grab videos from a wide variety of sites: vimeo, TikTok, dailymotion, facebook, Instagram, twitter, reddit, etc. Just try your site of choice and it may return a valid file.

This fix is available in 1.0.8. Feel free to re-open or create a new issue if you experience any more problems.

UplinkPhobia commented 3 days ago

Hey, The current implementation breaks linux compatibility as it tries using yt-dlp.exe

modestimpala commented 3 days ago

Hi @UplinkPhobia

Good catch, it seems YoutubeDLSharp defaults to "Windows" on NET45 image

I made a custom dll but I dont have Valheim setup in Linux currently. I understand it has a native client it seems? I can try and get it set up later. You can try replacing your YoutubeDLSharp.dll in OOD_LIB with this custom one and see if it works: YoutubeDLSharp.zip

UplinkPhobia commented 2 days ago

It seems to still be searching for a .exe. I should have put the error log earlier but it doesn't seem to have changed:

[Info   :     Trace] [yt-dlp] Arguments:  -g -f "best" -- "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
[Error  : Unity Log] Win32Exception: ApplicationName='/home/user/.local/share/Steam/steamapps/common/Valheim/yt-dlp.exe', CommandLine=' -g -f "best" -- "https://www.youtube.com/watch?v=dQw4w9WgXcQ"', CurrentDirectory='', Native error= Access denied
Stack trace:
System.Diagnostics.Process.StartWithCreateProcess (System.Diagnostics.ProcessStartInfo startInfo) (at <1878a84e5d5c42539d36f7fca65b9685>:0)
System.Diagnostics.Process.Start () (at <1878a84e5d5c42539d36f7fca65b9685>:0)
(wrapper remoting-invoke-with-check) System.Diagnostics.Process.Start()
YoutubeDLSharp.YoutubeDLProcess+<>c__DisplayClass25_0.<RunAsync>b__4 () (at <62031c426a2f4018bc87401cd730916c>:0)
System.Threading.Tasks.Task`1[TResult].InnerInvoke () (at <5aefc10cb7a348a6a66a4e2036c11d65>:0)
System.Threading.Tasks.Task.Execute () (at <5aefc10cb7a348a6a66a4e2036c11d65>:0)
--- End of stack trace from previous location where exception was thrown ---
YoutubeDLSharp.YoutubeDLProcess.RunAsync (System.String[] urls, YoutubeDLSharp.Options.OptionSet options, System.Threading.CancellationToken ct, System.IProgress`1[T] progress) (at <62031c426a2f4018bc87401cd730916c>:0)
YoutubeDLSharp.Helpers.ProcessRunner.RunThrottled (YoutubeDLSharp.YoutubeDLProcess process, System.String[] urls, YoutubeDLSharp.Options.OptionSet options, System.Threading.CancellationToken ct, System.IProgress`1[T] progress) (at <62031c426a2f4018bc87401cd730916c>:0)
YoutubeDLSharp.YoutubeDL.RunWithOptions (System.String url, YoutubeDLSharp.Options.OptionSet options, System.Threading.CancellationToken ct, System.IProgress`1[T] progress, System.IProgress`1[T] output, System.Boolean showArgs) (at <62031c426a2f4018bc87401cd730916c>:0)
Rethrow as AggregateException: One or more errors occurred. (ApplicationName='/home/user/.local/share/Steam/steamapps/common/Valheim/yt-dlp.exe', CommandLine=' -g -f "best" -- "https://www.youtube.com/watch?v=dQw4w9WgXcQ"', CurrentDirectory='', Native error= Access denied)
System.Threading.Tasks.Task.ThrowIfExceptional (System.Boolean includeTaskCanceledExceptions) (at <5aefc10cb7a348a6a66a4e2036c11d65>:0)
System.Threading.Tasks.Task`1[TResult].GetResultCore (System.Boolean waitCompletionNotification) (at <5aefc10cb7a348a6a66a4e2036c11d65>:0)
System.Threading.Tasks.Task`1[TResult].get_Result () (at <5aefc10cb7a348a6a66a4e2036c11d65>:0)
OdinOnDemand.Utils.Net.Explode.DLSharp+<GetVideoUrl>d__14.MoveNext () (at <ed64a67572474d6cadfc9a6b6baf9fe1>:0)
UnityEngine.SetupCoroutine.InvokeMoveNext (System.Collections.IEnumerator enumerator, System.IntPtr returnValueAddress) (at <bbfcdb8e91a44ae79d53e845fd06b4b5>:0)

As far as I know I didn't mess up the installation of the .dll you provided so I would imagine that something else is leading it to search for a yt-dlp.exe?

modestimpala commented 2 days ago

Thanks for the extra log details. I'm not super familiar with how Bepinex works on Linux, such as if the game runs Native but the dll code detects the environment is Windows due to Wine or Proton layers. Either that or the code is still returning the wrong path, but if it detects Linux it should look for the executable sans "exe".

I'm going to have to set up a dev environment and look into this closer to see what solutions I can come up with. I appreciate you testing the dll for me!