Add video bitrate setting for HomeKit source
This commit is contained in:
@@ -133,12 +133,19 @@ func Init() {
|
|||||||
var log zerolog.Logger
|
var log zerolog.Logger
|
||||||
var servers map[string]*server
|
var servers map[string]*server
|
||||||
|
|
||||||
func streamHandler(url string) (core.Producer, error) {
|
func streamHandler(rawURL string) (core.Producer, error) {
|
||||||
if srtp.Server == nil {
|
if srtp.Server == nil {
|
||||||
return nil, errors.New("homekit: can't work without SRTP server")
|
return nil, errors.New("homekit: can't work without SRTP server")
|
||||||
}
|
}
|
||||||
|
|
||||||
return homekit.Dial(url, srtp.Server)
|
rawURL, rawQuery, _ := strings.Cut(rawURL, "#")
|
||||||
|
client, err := homekit.Dial(rawURL, srtp.Server)
|
||||||
|
if client != nil && rawQuery != "" {
|
||||||
|
query := streams.ParseQuery(rawQuery)
|
||||||
|
client.Bitrate = parseBitrate(query.Get("bitrate"))
|
||||||
|
}
|
||||||
|
|
||||||
|
return client, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func hapPairSetup(w http.ResponseWriter, r *http.Request) {
|
func hapPairSetup(w http.ResponseWriter, r *http.Request) {
|
||||||
@@ -199,3 +206,24 @@ func findHomeKitURL(stream *streams.Stream) string {
|
|||||||
|
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func parseBitrate(s string) int {
|
||||||
|
n := len(s)
|
||||||
|
if n == 0 {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
var k int
|
||||||
|
switch n--; s[n] {
|
||||||
|
case 'K':
|
||||||
|
k = 1024
|
||||||
|
s = s[:n]
|
||||||
|
case 'M':
|
||||||
|
k = 1024 * 1024
|
||||||
|
s = s[:n]
|
||||||
|
default:
|
||||||
|
k = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
return k * core.Atoi(s)
|
||||||
|
}
|
||||||
|
|||||||
@@ -15,7 +15,8 @@ type Stream struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewStream(
|
func NewStream(
|
||||||
client *hap.Client, videoCodec *VideoCodec, audioCodec *AudioCodec, videoSession, audioSession *srtp.Session,
|
client *hap.Client, videoCodec *VideoCodec, audioCodec *AudioCodec,
|
||||||
|
videoSession, audioSession *srtp.Session, bitrate int,
|
||||||
) (*Stream, error) {
|
) (*Stream, error) {
|
||||||
stream := &Stream{
|
stream := &Stream{
|
||||||
id: core.RandString(16, 0),
|
id: core.RandString(16, 0),
|
||||||
@@ -30,11 +31,17 @@ func NewStream(
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if bitrate != 0 {
|
||||||
|
bitrate /= 1024 // convert bps to kbps
|
||||||
|
} else {
|
||||||
|
bitrate = 4096 // default kbps for general FullHD camera
|
||||||
|
}
|
||||||
|
|
||||||
videoCodec.RTPParams = []RTPParams{
|
videoCodec.RTPParams = []RTPParams{
|
||||||
{
|
{
|
||||||
PayloadType: 99,
|
PayloadType: 99,
|
||||||
SSRC: videoSession.Local.SSRC,
|
SSRC: videoSession.Local.SSRC,
|
||||||
MaxBitrate: 299,
|
MaxBitrate: uint16(bitrate), // iPhone query 299Kbps, iPad/AppleTV query 802Kbps
|
||||||
RTCPInterval: 0.5,
|
RTCPInterval: 0.5,
|
||||||
MaxMTU: []uint16{1378},
|
MaxMTU: []uint16{1378},
|
||||||
},
|
},
|
||||||
@@ -43,7 +50,7 @@ func NewStream(
|
|||||||
{
|
{
|
||||||
PayloadType: 110,
|
PayloadType: 110,
|
||||||
SSRC: audioSession.Local.SSRC,
|
SSRC: audioSession.Local.SSRC,
|
||||||
MaxBitrate: 24,
|
MaxBitrate: 24, // any iDevice query 24Kbps (this is OK for 16KHz and 1 channel)
|
||||||
RTCPInterval: 5,
|
RTCPInterval: 5,
|
||||||
|
|
||||||
ComfortNoisePayloadType: []uint8{13},
|
ComfortNoisePayloadType: []uint8{13},
|
||||||
|
|||||||
@@ -28,6 +28,8 @@ type Client struct {
|
|||||||
audioSession *srtp.Session
|
audioSession *srtp.Session
|
||||||
|
|
||||||
stream *camera.Stream
|
stream *camera.Stream
|
||||||
|
|
||||||
|
Bitrate int // in bits/s
|
||||||
}
|
}
|
||||||
|
|
||||||
func Dial(rawURL string, server *srtp.Server) (*Client, error) {
|
func Dial(rawURL string, server *srtp.Server) (*Client, error) {
|
||||||
@@ -132,7 +134,7 @@ func (c *Client) Start() error {
|
|||||||
c.audioSession = &srtp.Session{Local: c.srtpEndpoint()}
|
c.audioSession = &srtp.Session{Local: c.srtpEndpoint()}
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
c.stream, err = camera.NewStream(c.hap, videoCodec, audioCodec, c.videoSession, c.audioSession)
|
c.stream, err = camera.NewStream(c.hap, videoCodec, audioCodec, c.videoSession, c.audioSession, c.Bitrate)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user