Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 25 additions & 8 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,28 @@ import (
"net"
"os"
"os/signal"
"path/filepath"
"runtime"
"sync"

"distancedesktop/captured/pipelines"
"distancedesktop/captured/pipelines/linux"
"distancedesktop/captured/pipelines/macos"
"distancedesktop/captured/pipelines/windows"
)

var pipeline pipelines.Pipeline

// socketPath returns the filesystem path for one of the daemon's unix
// sockets. On Windows, AF_UNIX sockets still use filesystem paths, so the
// sockets land in the temp dir instead of /tmp.
func socketPath(name string) string {
if runtime.GOOS == "windows" {
return filepath.Join(os.TempDir(), name)
}
return filepath.Join("/tmp", name)
}

func main() {
listen := flag.String("listen", "", "TCP address for remote control (e.g. :9090)")
source := flag.String("source", "kms", "capture source on linux: kms|pipewire|x11")
Expand All @@ -30,19 +42,24 @@ func main() {
pipeline = macos.New()
case "linux":
pipeline = linux.New(*source)
case "windows":
pipeline = windows.New()
default:
log.Fatalf("unsupported platform: %s", runtime.GOOS)
}

ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt)
defer stop()

os.Remove("/tmp/captured.socket")
ul, err := net.Listen("unix", "/tmp/captured.socket")
controlSock := socketPath("captured.socket")
mediaSock := socketPath("captured-media.socket")

os.Remove(controlSock)
ul, err := net.Listen("unix", controlSock)
if err != nil {
log.Fatal(err)
}
log.Println("unix: /tmp/captured.socket")
log.Println("unix:", controlSock)

var tl net.Listener
if *listen != "" {
Expand Down Expand Up @@ -93,8 +110,8 @@ func main() {
continue
}
stream = s
os.Remove("/tmp/captured-media.socket")
ml, err := net.Listen("unix", "/tmp/captured-media.socket")
os.Remove(mediaSock)
ml, err := net.Listen("unix", mediaSock)
if err != nil {
stream.Close()
stream = nil
Expand Down Expand Up @@ -126,7 +143,7 @@ func main() {
streamMu.Unlock()
enc.Encode(map[string]any{
"type": "stream-started",
"socket": "/tmp/captured-media.socket",
"socket": mediaSock,
"format": "bgra",
})

Expand All @@ -136,7 +153,7 @@ func main() {
stream.Close()
stream = nil
}
// os.Remove("/tmp/captured-media.socket") - do NOT fucking do this
// os.Remove(mediaSock) - do NOT fucking do this
streamMu.Unlock()
enc.Encode(map[string]string{"type": "stream-stopped"})

Expand Down Expand Up @@ -184,5 +201,5 @@ func main() {
stream.Close()
}
streamMu.Unlock()
os.Remove("/tmp/captured-media.socket")
os.Remove(mediaSock)
}
2 changes: 2 additions & 0 deletions pipelines/macos/pipeline.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//go:build darwin

package macos

import (
Expand Down
30 changes: 30 additions & 0 deletions pipelines/macos/stub_other.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
//go:build !darwin

// Package macos provides the macOS capture pipeline. On non-Darwin hosts it
// compiles to a stub so the package remains importable; the real
// implementation lives behind the `darwin` build tag.
package macos

import (
"context"
"fmt"

"distancedesktop/captured/pipelines"
)

type unsupportedPipeline struct{}

// New always returns the unsupported stub on non-Darwin platforms.
func New() pipelines.Pipeline { return &unsupportedPipeline{} }

func (p *unsupportedPipeline) ListDisplays(ctx context.Context) ([]pipelines.DisplayMeta, error) {
return nil, fmt.Errorf("macos pipeline is only supported on darwin")
}

func (p *unsupportedPipeline) SupportedFormats() []pipelines.FrameFormat {
return nil
}

func (p *unsupportedPipeline) StartStream(ctx context.Context, displayID uint32, fps int) (pipelines.FrameStream, error) {
return nil, fmt.Errorf("macos pipeline is only supported on darwin")
}
Loading
Loading