Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bug(core/playback/mpv): jukebox mode under windows - #2767 #2774

Merged
merged 11 commits into from Apr 14, 2024

Conversation

apkatsikas
Copy link
Contributor

@apkatsikas apkatsikas commented Jan 7, 2024

Closes

#2767

Description

Fixes Jukebox mode when running under Windows.

Windows needs to use a named pipe instead of a file in the temp folder for the socket with mpv. See https://mpv.io/manual/master#using-mpv-from-other-programs-or-scripts which states regarding --input-ipc-server flag for script control
This gives you access to the JSON IPC over unix domain sockets (or named pipes on Windows).

See Windows docs on Named Pipes - https://learn.microsoft.com/en-us/windows/win32/ipc/pipe-names

The pipe server cannot create a pipe on another computer, so CreateNamedPipe must use a period for the server name, as shown in the following example.

\\.\pipe\PipeName

This is also expounded on here - https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-createnamedpipea

Changes

  • Use named pipe for socket path under Windows during mpv playback/Jukebox mode
  • Change function name
  • Unexport function

Tested regular playback and Jukebox mode via rest/jukeboxControl endpoint, on Windows and Linux.

Use named pipe for socket path under windows during mpv playback, change function name, unexport function

Signed-off-by: apkatsikas <apkatsikas@gmail.com>
@apkatsikas apkatsikas mentioned this pull request Jan 7, 2024
3 tasks
Copy link

github-actions bot commented Jan 7, 2024

Download the artifacts for this pull request:

Fix typo

Signed-off-by: apkatsikas <apkatsikas@gmail.com>
@apkatsikas
Copy link
Contributor Author

apkatsikas commented Jan 8, 2024

I noticed two errors being emitted when a track ends and goes to next queued during Jukebox play on Windows, that do not seem to affect playback experience, but are probably specific to how Named Pipes are treated in Windows:

  • "Error sending quit command to mpv-ipc socket" error="trying to send command on closed mpv client" -
    log.Error("Error sending quit command to mpv-ipc socket", err)
    - my guess is Windows is automatically handling the closing of the Named pipe and we don't have to Conn.Call("quit") here.
  • "error cleaning up socketfile": " \\.\pipe\mpvsocket\mpv-ctrl-b400e1e2db7708379f89740f8a897905.socket="!!!!Invalid number of arguments in log call!!!!" -
    log.Error("error cleaning up socketfile: ", t.IPCSocketName)
    - the Named Pipe docs say An instance of a named pipe is always deleted when the last handle to the instance of the named pipe is closed. - so I don't think we should call os.Remove on Windows https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-createnamedpipea#remarks

Neither of these errors is affecting the user experience (to my knowledge) but it's not great to throw these errors on Windows due to its special behavior with Named Pipes. The question is - do we want to "fix" these issues in this PR or handle them later?

@deluan
Copy link
Member

deluan commented Jan 19, 2024

Hey, thanks! I'll take a look and get back to you as soon as I can!

@ms140569
Copy link
Contributor

ms140569 commented Apr 9, 2024

The PR looks totally sensible to me, although i haven't compiled it under Windows. @apkatsikas if you tell/point me on how to build on windows I'll doublecheck for you. Windows is not my Hometurf ...

Regarding the Socket close issue my cut is to handle/fix this within this bug since it's so related.

@apkatsikas
Copy link
Contributor Author

The PR looks totally sensible to me, although i haven't compiled it under Windows. @apkatsikas if you tell/point me on how to build on windows I'll doublecheck for you. Windows is not my Hometurf ...

Regarding the Socket close issue my cut is to handle/fix this within this bug since it's so related.

makes sense to me. i can rebase and fix all instances outlined soon. in the mean time, if you want to try the build, you can download the binaries.zip created by the GitHub Actions bot above

image

https://nightly.link/navidrome/navidrome/actions/artifacts/1152903166.zip

Early return for Close on Windows

Signed-off-by: apkatsikas <apkatsikas@gmail.com>
Merge master and move logic into utils function

Signed-off-by: apkatsikas <apkatsikas@gmail.com>
Update import and run prettier

Signed-off-by: apkatsikas <apkatsikas@gmail.com>
`https://www.last.fm/api/auth/?api_key=${localStorage.getItem('lastfm-apikey')}&cb=${callbackUrl}`,
`https://www.last.fm/api/auth/?api_key=${localStorage.getItem(
'lastfm-apikey',
)}&cb=${callbackUrl}`,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was required to run prettier before I could push due to git hooks.

Update function name

Signed-off-by: apkatsikas <apkatsikas@gmail.com>
@@ -104,6 +105,11 @@ func (t *MpvTrack) Pause() {
}

func (t *MpvTrack) Close() {
// Windows automatically handles closing
// and cleaning up named pipe
if runtime.GOOS == "windows" {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is not a good practice to use runtime.GOOS in your files (unless it is a really small check). Usually we create one file for each variation and use build tags to control which version to use.

For an example, see scanner/metadata/taglib/get_filename.go and scanner/metadata/taglib/get_filename_win.go

In your case I'd have two Close() methods in different files, one for windows (do nothing) and the other for all other platforms with the actual code.

Let me know if it makes sense to you or if you want me to do that.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah was wondering about this and hoping to get feedback on what best practice is for this project. makes sense and thank you for the examples - will give it a shot and report back

utils/files.go Outdated

"github.com/google/uuid"
)

func TempFileName(prefix, suffix string) string {
return filepath.Join(os.TempDir(), prefix+uuid.NewString()+suffix)
func RandomSocketOrFileName(prefix, suffix string) string {
Copy link
Member

@deluan deluan Apr 13, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I rather leave this function (TempFileName) alone and create a SocketName in the core/playback/mpv package, also selectable by build tags

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sounds good

Copy link
Member

@deluan deluan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, see my comments above.

Create track_close files for both platforms and move MpvTrack Close into new file

Signed-off-by: apkatsikas <apkatsikas@gmail.com>
Create SocketName function for both platforms, restore name of TempFileName

Signed-off-by: apkatsikas <apkatsikas@gmail.com>
Add missing params to SocketName on windows

Signed-off-by: apkatsikas <apkatsikas@gmail.com>
@apkatsikas apkatsikas requested a review from deluan April 14, 2024 17:46
@deluan deluan merged commit c2f932c into navidrome:master Apr 14, 2024
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants