Dacast support #1091
Unanswered
peterpaulis
asked this question in
Q&A
Dacast support
#1091
Replies: 2 comments 3 replies
-
Please try these code. rtmpConneciton.connect('rtmp://1586409386:2937cf25500b742d@0eec355e-5ee3-4d54-b80c-e30cd0383c71.dacastmmd.pri.lldns.net/dacastmmd/')
rtmpStream.publish("39a08f38c0664e5095fdd8b1eb353bda", type: .live) witout "/" rtmpConneciton.connect('rtmp://1586409386:2937cf25500b742d@0eec355e-5ee3-4d54-b80c-e30cd0383c71.dacastmmd.pri.lldns.net/dacastmmd')
rtmpStream.publish("39a08f38c0664e5095fdd8b1eb353bda", type: .live) |
Beta Was this translation helpful? Give feedback.
3 replies
-
I come a bit closer but still not resolved. The problem is that DaCast needs import Foundation
import var CommonCrypto.CC_MD5_DIGEST_LENGTH
import func CommonCrypto.CC_MD5
import typealias CommonCrypto.CC_LONG
struct Preference {
static var defaultInstance = Preference(baseURL: "96e4ebbd-b529-41db--66cdb1d845ec.dacastmmd.pri.lldns.net", app: "dacastmmd", streamName: "a3503f28a53dc503748fedc61", auth: .llnw(LLNWAuth(user: "715259", password: "f98220d7e2db")))
let uri: String
let app: String
let streamName: String
let baseURL: String
let auth: RMTPAuthType?
/// Basic format: rtmp://[baseURL]/[app]/[streamName]
init(baseURL: String, app: String, streamName: String, auth: RMTPAuthType? = nil) {
self.streamName = streamName
self.baseURL = baseURL
self.app = app
self.auth = auth
if let auth {
switch auth {
case let .http(user, password):
uri = "rtmp://\(user):\(password)@\(baseURL)/\(app)/\(streamName)"
case .llnw(let llnwAuth):
let authParams = llnwAuth.createAuthParams(app: app, streamName: streamName)
uri = "rtmp://\(baseURL)/\(app)/\(streamName)?\(authParams)"
}
} else {
uri = "rtmp://\(baseURL)/\(app)/\(streamName)"
}
}
}
enum RMTPAuthType {
/// Adds credentials into the url rtmp://[username]:[password]@[url]/[application]/[stream_name]
case http(user: String, password: String)
/// Limelight auth type which is used for example by DaCast
case llnw(LLNWAuth)
}
struct LLNWAuth {
let user: String
let password: String
let nonce: String
init(user: String, password: String) {
self.user = user
self.password = password
self.nonce = Self.createNonce()
}
static func createNonce() -> String {
let length = 64
let letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
return String((0..<length).map { _ in letters.randomElement()! })
}
private func random4Bytes() -> Data {
var bytes = Data(count: 4)
_ = bytes.withUnsafeMutableBytes { bytesBytes in
SecRandomCopyBytes(kSecRandomDefault, 4, bytesBytes)
}
return bytes
}
func createAuthParams(app: String, streamName: String) -> String {
let authmod = "llnw"
let realm = "live"
let method = "publish"
let qop = "auth"
// nc = 1..connection count (or rather, number of times cnonce has been reused)
var nc = 1
let ncHex = Data(bytes: &nc, count: MemoryLayout.size(ofValue: nc)).hexEncoded()
let cnonce = random4Bytes().hexEncoded()
let hash1 = (user + ":" + realm + ":" + password).MD5().hexEncoded()
let hash2 = (method + ":/" + app + "/" + streamName).MD5().hexEncoded()
let hash3 = (hash1 + ":" + nonce + ":" + ncHex + ":" + cnonce + ":" + qop + ":" + hash2).MD5().hexEncoded()
return "authmod=\(authmod)&user=\(user)&nonce=\(nonce)&cnonce=\(cnonce)&nc=\(ncHex)&response=\(hash3)"
}
}
extension String {
func MD5() -> Data {
let length = Int(CC_MD5_DIGEST_LENGTH)
let messageData = self.data(using: .utf8)!
var digestData = Data(count: length)
_ = digestData.withUnsafeMutableBytes { digestBytes -> UInt8 in
messageData.withUnsafeBytes { messageBytes -> UInt8 in
if let messageBytesBaseAddress = messageBytes.baseAddress, let digestBytesBlindMemory = digestBytes.bindMemory(to: UInt8.self).baseAddress {
let messageLength = CC_LONG(messageData.count)
CC_MD5(messageBytesBaseAddress, messageLength, digestBytesBlindMemory)
}
return 0
}
}
return digestData
}
}
extension Data {
func hexEncoded() -> String {
return map { String(format: "%02hhx", $0) }.joined()
}
} Now it's actually sending data but DaCast won't process the stream data for some reason. |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
I try to record on Dacast
but i get a black screen
looks like this is due to auth that i provide in the url
"code": Optional("NetConnection.Connect.Rejected"), "description": Optional("[ AccessManager.Reject ] : [ code=403 need auth; authmod=llnw ]
as Dacast uses Limelight Networks auth... how to use Dacast with HaishinKit
Beta Was this translation helpful? Give feedback.
All reactions