golang实现Open Sound Control(OSC)协议的通信插件库go-osc的使用

Golang实现Open Sound Control(OSC)协议的通信插件库go-osc的使用

介绍

GoOSC是一个用于Golang的Open Sound Control (OSC)库,完全用Go语言实现。

特性

  • OSC Bundles,包括时间标签
  • OSC消息
  • OSC客户端
  • OSC服务器
  • 支持以下OSC参数类型:
    • ‘i’ (Int32)
    • ‘f’ (Float32)
    • ‘s’ (string)
    • ‘b’ (blob / 二进制数据)
    • ‘h’ (Int64)
    • ‘t’ (OSC时间标签)
    • ‘d’ (Double/int64)
    • ‘T’ (True)
    • ‘F’ (False)
    • ‘N’ (Nil)
  • 支持OSC地址模式,包括’*’、’?’、’{,}‘和’[]'通配符

安装

go get github.com/hypebeast/go-osc

使用示例

客户端示例

import "github.com/hypebeast/go-osc/osc"

func main() {
    // 创建OSC客户端,连接到localhost的8765端口
    client := osc.NewClient("localhost", 8765)
    
    // 创建一个新的OSC消息,地址为"/osc/address"
    msg := osc.NewMessage("/osc/address")
    
    // 向消息添加参数:int32、bool和string类型
    msg.Append(int32(111))
    msg.Append(true)
    msg.Append("hello")
    
    // 发送消息
    client.Send(msg)
}

服务器示例

package main

import "github.com/hypebeast/go-osc/osc"

func main() {
    // 设置服务器监听地址
    addr := "127.0.0.1:8765"
    
    // 创建标准调度器
    d := osc.NewStandardDispatcher()
    
    // 添加消息处理器,处理地址为"/message/address"的消息
    d.AddMsgHandler("/message/address", func(msg *osc.Message) {
        // 打印接收到的消息
        osc.PrintMessage(msg)
    })

    // 创建OSC服务器
    server := &osc.Server{
        Addr:       addr,
        Dispatcher: d,
    }
    
    // 启动服务器
    server.ListenAndServe()
}

完整通信示例

下面是一个完整的客户端和服务器通信示例:

server.go

package main

import (
	"fmt"
	"github.com/hypebeast/go-osc/osc"
)

func main() {
	addr := "127.0.0.1:8765"
	d := osc.NewStandardDispatcher()
	
	d.AddMsgHandler("/greet", func(msg *osc.Message) {
		fmt.Printf("Received message: %s\n", msg.Address)
		for i, arg := range msg.Arguments {
			fmt.Printf("Argument %d: %v\n", i, arg)
		}
	})

	server := &osc.Server{
		Addr:       addr,
		Dispatcher: d,
	}
	
	fmt.Println("OSC Server listening on", addr)
	server.ListenAndServe()
}

client.go

package main

import (
	"github.com/hypebeast/go-osc/osc"
	"time"
)

func main() {
	client := osc.NewClient("localhost", 8765)
	
	for i := 0; i < 5; i++ {
		msg := osc.NewMessage("/greet")
		msg.Append(int32(i))
		msg.Append(fmt.Sprintf("Message %d", i))
		msg.Append(time.Now().Unix())
		
		fmt.Printf("Sending message %d\n", i)
		client.Send(msg)
		
		time.Sleep(1 * time.Second)
	}
}

测试

make test

这个库提供了完整的OSC协议实现,可以方便地在Golang项目中集成OSC通信功能。通过上面的示例代码,你可以快速实现OSC客户端和服务器的开发。


更多关于golang实现Open Sound Control(OSC)协议的通信插件库go-osc的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang实现Open Sound Control(OSC)协议的通信插件库go-osc的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


使用go-osc实现Open Sound Control(OSC)通信

Open Sound Control(OSC)是一种用于音乐应用、多媒体设备和计算机之间的通信协议。在Go语言中,我们可以使用go-osc库来实现OSC协议的通信。下面我将详细介绍如何使用这个库。

安装go-osc

首先需要安装go-osc库:

go get github.com/hypebeast/go-osc/osc

基本概念

OSC通信包含两个主要部分:

  1. OSC客户端 - 发送OSC消息
  2. OSC服务器 - 接收和处理OSC消息

创建OSC服务器

下面是一个简单的OSC服务器实现:

package main

import (
	"fmt"
	"github.com/hypebeast/go-osc/osc"
)

func main() {
	// 创建服务器,监听端口12000
	server := &osc.Server{Addr: "127.0.0.1:12000"}

	// 添加消息处理器
	server.Handle("/test", func(msg *osc.Message) {
		// 打印接收到的消息
		fmt.Printf("Received OSC message: %s\n", msg.Address)
		
		// 打印所有参数
		for i, arg := range msg.Arguments {
			fmt.Printf("  Argument %d: %v\n", i, arg)
		}
	})

	// 启动服务器
	fmt.Println("Starting OSC server on 127.0.0.1:12000")
	if err := server.ListenAndServe(); err != nil {
		fmt.Printf("Server error: %v\n", err)
	}
}

创建OSC客户端

下面是发送OSC消息的客户端代码:

package main

import (
	"fmt"
	"github.com/hypebeast/go-osc/osc"
	"time"
)

func main() {
	// 创建客户端,连接到服务器127.0.0.1:12000
	client := osc.NewClient("127.0.0.1", 12000)

	// 创建消息,地址为/test
	msg := osc.NewMessage("/test")
	
	// 添加不同类型的参数
	msg.Append(int32(123))       // 32位整数
	msg.Append(3.14)             // 浮点数
	msg.Append("hello")          // 字符串
	msg.Append([]byte{'a', 'b'}) // 二进制数据
	msg.Append(true)             // 布尔值

	// 发送消息
	fmt.Println("Sending OSC message...")
	if err := client.Send(msg); err != nil {
		fmt.Printf("Error sending OSC message: %v\n", err)
		return
	}

	// 等待服务器处理
	time.Sleep(1 * time.Second)
}

高级用法

1. 处理不同类型的参数

server.Handle("/params", func(msg *osc.Message) {
	if len(msg.Arguments) > 0 {
		switch arg := msg.Arguments[0].(type) {
		case int32:
			fmt.Printf("Received int32: %d\n", arg)
		case float32:
			fmt.Printf("Received float32: %f\n", arg)
		case string:
			fmt.Printf("Received string: %s\n", arg)
		case []byte:
			fmt.Printf("Received blob: %v\n", arg)
		case bool:
			fmt.Printf("Received bool: %t\n", arg)
		default:
			fmt.Printf("Unknown type: %T\n", arg)
		}
	}
})

2. 发送定时消息

func sendPeriodicMessages(client *osc.Client) {
	ticker := time.NewTicker(1 * time.Second)
	defer ticker.Stop()

	for range ticker.C {
		msg := osc.NewMessage("/heartbeat")
		msg.Append(time.Now().Unix())
		if err := client.Send(msg); err != nil {
			fmt.Printf("Error sending heartbeat: %v\n", err)
		}
	}
}

3. 处理OSC Bundle

OSC Bundle可以包含多个消息和时间标签:

server.Handle("/bundle", func(bundle *osc.Bundle) {
	fmt.Printf("Received bundle with timestamp: %v\n", bundle.Timetag.Time())
	
	for _, elem := range bundle.Elements {
		if msg, ok := elem.(*osc.Message); ok {
			fmt.Printf("  Message: %s\n", msg.Address)
		} else if b, ok := elem.(*osc.Bundle); ok {
			fmt.Printf("  Nested bundle\n")
		}
	}
})

实际应用示例

下面是一个简单的音乐控制示例,模拟控制音乐播放器:

// 服务器端 - 音乐控制器
func setupMusicController() {
	server := &osc.Server{Addr: "127.0.0.1:12345"}
	
	// 播放/暂停控制
	server.Handle("/music/play", func(msg *osc.Message) {
		if len(msg.Arguments) > 0 {
			if play, ok := msg.Arguments[0].(bool); ok {
				if play {
					fmt.Println("Playing music")
				} else {
					fmt.Println("Pausing music")
				}
			}
		}
	})
	
	// 音量控制
	server.Handle("/music/volume", func(msg *osc.Message) {
		if len(msg.Arguments) > 0 {
			if vol, ok := msg.Arguments[0].(float32); ok {
				fmt.Printf("Setting volume to %.2f\n", vol)
			}
		}
	})
	
	// 跳转控制
	server.Handle("/music/seek", func(msg *osc.Message) {
		if len(msg.Arguments) > 0 {
			if pos, ok := msg.Arguments[0].(int32); ok {
				fmt.Printf("Seeking to position: %d\n", pos)
			}
		}
	})
	
	fmt.Println("Music controller ready on port 12345")
	server.ListenAndServe()
}

// 客户端 - 音乐控制界面
func sendMusicCommands() {
	client := osc.NewClient("127.0.0.1", 12345)
	
	// 播放
	playMsg := osc.NewMessage("/music/play")
	playMsg.Append(true)
	client.Send(playMsg)
	
	// 设置音量
	volMsg := osc.NewMessage("/music/volume")
	volMsg.Append(float32(0.8))
	client.Send(volMsg)
	
	// 跳转
	seekMsg := osc.NewMessage("/music/seek")
	seekMsg.Append(int32(120)) // 跳转到2分钟位置
	client.Send(seekMsg)
	
	// 暂停
	pauseMsg := osc.NewMessage("/music/play")
	pauseMsg.Append(false)
	client.Send(pauseMsg)
}

注意事项

  1. OSC协议没有内置的错误处理机制,需要自己实现
  2. 默认情况下,go-osc使用UDP协议,如果需要可靠传输,可以考虑在应用层实现确认机制
  3. 对于大量数据传输,考虑使用OSC Bundle来批量发送消息
  4. 注意参数类型的匹配,Go和OSC类型系统不完全一致

通过go-osc库,我们可以方便地在Go中实现OSC协议的通信,适用于音乐软件、多媒体控制和交互艺术等应用场景。

回到顶部