fix: AirPlay mDNS 发现修复 — MAC地址/公钥/gid

- MAC地址从网络接口获取真实地址 (非全零)
- Ed25519密钥对改为立即初始化 (非lazy) 确保pk在注册前可用
- 添加gid (group UUID) 关联 _airplay 和 _raop 服务
- _airplay 添加 statusFlags TXT 记录
This commit is contained in:
2026-05-31 12:58:06 +08:00
parent f635303f2a
commit b8d0455e2e
2 changed files with 29 additions and 2 deletions

View File

@@ -4,6 +4,7 @@ import android.content.Context
import android.net.nsd.NsdManager
import android.net.nsd.NsdServiceInfo
import android.util.Log
import java.net.NetworkInterface
class AirPlayMdnsService(private val context: Context) {
@@ -18,10 +19,33 @@ class AirPlayMdnsService(private val context: Context) {
private const val MODEL = "AppleTV5,3"
private const val SRCVERS = "220.68"
private const val PROTOVERS = "1.1"
fun getMacAddress(): String {
try {
val interfaces = NetworkInterface.getNetworkInterfaces()
while (interfaces.hasMoreElements()) {
val iface = interfaces.nextElement()
val mac = iface.hardwareAddress ?: continue
if (mac.size == 6 && mac[0] != 0.toByte()) {
return mac.joinToString(":") { b -> "%02X".format(b) }
}
}
} catch (_: Exception) {}
val hash = (android.os.Build.SERIAL ?: android.os.Build.MODEL).hashCode()
return String.format("%02X:%02X:%02X:%02X:%02X:%02X",
(hash shr 24) and 0xFF,
(hash shr 16) and 0xFF,
(hash shr 8) and 0xFF,
hash and 0xFF,
((hash * 31) shr 16) and 0xFF,
((hash * 31) shr 24) and 0xFF
)
}
}
@Volatile var deviceName: String = android.os.Build.MODEL
@Volatile var macAddress: String = "00:00:00:00:00:00"
@Volatile var macAddress: String = getMacAddress()
@Volatile var groupId: String = java.util.UUID.randomUUID().toString()
private var nsdManager: NsdManager =
context.applicationContext.getSystemService(Context.NSD_SERVICE) as NsdManager
@@ -61,11 +85,13 @@ class AirPlayMdnsService(private val context: Context) {
setAttribute("model", MODEL)
setAttribute("pk", publicKeyHex)
setAttribute("pi", java.util.UUID.randomUUID().toString())
setAttribute("gid", groupId)
setAttribute("srcvers", SRCVERS)
setAttribute("vv", "2")
setAttribute("protovers", PROTOVERS)
setAttribute("manufacturer", "Apple Inc.")
setAttribute("osvers", android.os.Build.VERSION.RELEASE)
setAttribute("statusFlags", "4")
}
airplayListener = createListener("AirPlay")
@@ -103,6 +129,7 @@ class AirPlayMdnsService(private val context: Context) {
setAttribute("am", MODEL)
setAttribute("pk", publicKeyHex)
setAttribute("sf", FLAGS)
setAttribute("gid", groupId)
setAttribute("tp", "UDP")
setAttribute("vn", "65537")
setAttribute("vs", SRCVERS)

View File

@@ -57,7 +57,7 @@ class AirPlayProtocol(
private var clientSocket: Socket? = null
private var scope: CoroutineScope? = null
private val ed25519KeyPair by lazy { generateEd25519KeyPair() }
private val ed25519KeyPair = generateEd25519KeyPair()
private val sessionId = UUID.randomUUID().toString()
private var pairingState: PairingState = PairingState()