mirror of https://bitbucket.org/ausocean/av.git
Wrote rtmpSetupUrl, but need to test
This commit is contained in:
parent
e04ae76dcf
commit
e5696f389d
169
rtmp/rtmp.go
169
rtmp/rtmp.go
|
@ -146,6 +146,18 @@ var setDataFrame = AVC("@setDataFrame")
|
|||
|
||||
var packetSize = [...]int{12, 8, 4, 1}
|
||||
|
||||
var RTMPProtocolStringsLower = [...]string{
|
||||
"rtmp",
|
||||
"rtmpt",
|
||||
"rtmpe",
|
||||
"rtmpte",
|
||||
"rtmps",
|
||||
"rtmpts",
|
||||
"",
|
||||
"",
|
||||
"rtmfp",
|
||||
}
|
||||
|
||||
// Session provides an interface for sending flv tags over rtmp.
|
||||
type Session interface {
|
||||
Open() error
|
||||
|
@ -318,13 +330,40 @@ func (s *session) Open() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Close terminates the rtmp connection
|
||||
func (s *session) Close() error {
|
||||
if s.rtmp == nil {
|
||||
return Err(3)
|
||||
}
|
||||
ret := endSession(s.rtmp)
|
||||
s.rtmp = nil
|
||||
if ret != 0 {
|
||||
return Err(ret)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Write writes a frame (flv tag) to the rtmp connection
|
||||
func (s *session) Write(data []byte) (int, error) {
|
||||
if s.rtmp == nil {
|
||||
return 0, Err(3)
|
||||
}
|
||||
if C.RTMP_IsConnected(s.rtmp) == 0 {
|
||||
return 0, Err(1)
|
||||
}
|
||||
//if C.RTMP_Write(s.rtmp,(*C.char)(unsafe.Pointer(&data[0])),C.int(len(data))) == 0 {
|
||||
if rtmpWrite(s.rtmp, data) == 0 {
|
||||
return 0, Err(2)
|
||||
}
|
||||
return len(data), nil
|
||||
}
|
||||
|
||||
func startSession(rtmp *C.RTMP, u string, timeout uint32) (*C.RTMP, error) {
|
||||
url := C.CString(u)
|
||||
connect_timeout := C.int(timeout)
|
||||
rtmp = rtmpAlloc()
|
||||
rtmpInit(rtmp)
|
||||
rtmp.Link.timeout = connect_timeout
|
||||
if C.RTMP_SetupURL(rtmp, url) == 0 {
|
||||
if rtmpSetupUrl(rtmp, u) == 0 {
|
||||
C.RTMP_Close(rtmp)
|
||||
C.RTMP_Free(rtmp)
|
||||
return nil, errors.New("rtmp startSession: Failed to setup URL!")
|
||||
|
@ -366,17 +405,75 @@ func rtmpInit(r *C.RTMP) {
|
|||
r.Link.swfAge = 30
|
||||
}
|
||||
|
||||
// Close terminates the rtmp connection
|
||||
func (s *session) Close() error {
|
||||
if s.rtmp == nil {
|
||||
return Err(3)
|
||||
func rtmpSetupUrl(r *C.RTMP, u string) int32 {
|
||||
length := len(u)
|
||||
url := goStrToCStr(u)
|
||||
|
||||
var opt, arg AVal
|
||||
var p1, p2 *byte
|
||||
ptr := strchr(url, byte(' '))
|
||||
var ret, len int32
|
||||
var port uint32
|
||||
port = 0
|
||||
|
||||
len = strlen(url)
|
||||
ret = int32(C.RTMP_ParseURL((*C.char)(unsafe.Pointer(url)), &r.Link.protocol, &r.Link.hostname,
|
||||
(*C.uint)(&port), &r.Link.playpath0, &r.Link.app))
|
||||
|
||||
if ret == 0 {
|
||||
return ret
|
||||
}
|
||||
ret := endSession(s.rtmp)
|
||||
s.rtmp = nil
|
||||
if ret != 0 {
|
||||
return Err(ret)
|
||||
|
||||
r.Link.port = C.ushort(port)
|
||||
r.Link.playpath = r.Link.playpath0
|
||||
|
||||
if r.Link.tcUrl.av_len == 0 {
|
||||
r.Link.tcUrl.av_val = url
|
||||
if r.Link.app.av_len != 0 {
|
||||
if int(uintptr(unsafe.Pointer(r.Link.app.av_val))) <
|
||||
int(uintptr(incBytePtr(url, len))) {
|
||||
|
||||
r.Link.tcUrl.av_len = r.Link.app.av_len +
|
||||
int(uintptr(decBytePtr(r.Link.app.av_val, int(uintptr(unsafe.Pointer(url))))))
|
||||
} else {
|
||||
len = r.Link.hostname.av_len + r.Link.app.av_len +
|
||||
int(unsafe.Sizeof("rtmpte://:65535/"))
|
||||
|
||||
r.Link.tcUrl.av_val = (*C.char)(allocate(uintptr(len)))
|
||||
hostname := string(ptrToSlice(unsafe.Pointer(r.Link.hostname.av_val),
|
||||
int(r.Link.hostname.av_len)))
|
||||
|
||||
app := string(ptrToSlice(unsafe.Pointer(r.Link.app.av_val),
|
||||
int(r.Link.app.av_len)))
|
||||
|
||||
fString := fmt.Sprintf("%v://%v:%v/%v",
|
||||
RTMPProtocolStringsLower[r.Link.protocol], hostname, r.Link.port, app)
|
||||
|
||||
r.Link.tcUrl.av_val = (*C.char)(goStrToCStr(fString))
|
||||
r.Link.tcUrl.av_len = len(RTMPProtocolStringsLower[r.Link.protocol]) +
|
||||
len(string("://")) + len(hostname) + len(string(":")) +
|
||||
len(strconv.Itoa(int(r.Link.port))) + len(string("/")) + len(app)
|
||||
|
||||
r.Link.lFlags |= RTMP_LF_FTCU
|
||||
}
|
||||
} else {
|
||||
r.Link.tcUrl.av_len = strlen(url)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
||||
C.SocksSetup(r, &r.Link.sockshost)
|
||||
|
||||
if r.Link.port == 0 {
|
||||
switch {
|
||||
case r.Link.Protocol & RRTMP_FEATURE_SSL:
|
||||
r.Link.port = 433
|
||||
case r.Link.protocol & RTMP_FEATURE_HTTP:
|
||||
r.Link.port = 80
|
||||
default:
|
||||
r.Link.port = 1935
|
||||
}
|
||||
}
|
||||
return 1
|
||||
}
|
||||
|
||||
func endSession(rtmp *C.RTMP) uint32 {
|
||||
|
@ -389,21 +486,6 @@ func endSession(rtmp *C.RTMP) uint32 {
|
|||
return 0
|
||||
}
|
||||
|
||||
// Write writes a frame (flv tag) to the rtmp connection
|
||||
func (s *session) Write(data []byte) (int, error) {
|
||||
if s.rtmp == nil {
|
||||
return 0, Err(3)
|
||||
}
|
||||
if C.RTMP_IsConnected(s.rtmp) == 0 {
|
||||
return 0, Err(1)
|
||||
}
|
||||
//if C.RTMP_Write(s.rtmp,(*C.char)(unsafe.Pointer(&data[0])),C.int(len(data))) == 0 {
|
||||
if rtmpWrite(s.rtmp, data) == 0 {
|
||||
return 0, Err(2)
|
||||
}
|
||||
return len(data), nil
|
||||
}
|
||||
|
||||
// rtmpWrite writes data to the current rtmp connection encapsulated by r
|
||||
func rtmpWrite(r *C.RTMP, data []byte) int {
|
||||
buf := sliceToPtr(data)
|
||||
|
@ -968,6 +1050,41 @@ func avQueue(vals **C.RTMP_METHOD, num *int, av *C.AVal, txn int) {
|
|||
int(unsafe.Sizeof(rtmpMethodPtr))))).name.av_val = (*C.char)(tmp)
|
||||
}
|
||||
|
||||
func goStrToCStr(str string) *byte {
|
||||
l := len(str)
|
||||
slice := make([]byte, l+1)
|
||||
ptr := unsafe.Pointer(&[]byte(str)[0])
|
||||
for i := 0; i < l; i++ {
|
||||
slice[i] = *indxBytePtr(ptr, i)
|
||||
}
|
||||
slice[l] = '\000'
|
||||
return slice
|
||||
}
|
||||
|
||||
func strlen(str *byte) int32 {
|
||||
for i := 0; true; i++ {
|
||||
ptr = indxBytePtr(unsafe.Pointer(str), i)
|
||||
if *ptr == '\000' {
|
||||
return i
|
||||
}
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func strchr(str *byte, val byte) *byte {
|
||||
var ptr *byte
|
||||
for i := 0; true; i++ {
|
||||
ptr = indxBytePtr(unsafe.Pointer(str), i)
|
||||
if *ptr == val {
|
||||
return ptr
|
||||
}
|
||||
if *ptr == '\000' {
|
||||
break
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func allocate(nOfBytes uintptr) unsafe.Pointer {
|
||||
mem := make([]byte, int(nOfBytes))
|
||||
return unsafe.Pointer(&mem[0])
|
||||
|
|
Loading…
Reference in New Issue