Merge commit '6bd7fac875d9e9009915053d8a590abb372c5679' into feature/livekit-upgrade-1.13.1

This commit is contained in:
2026-06-25 23:54:33 +09:00
291 changed files with 37631 additions and 15381 deletions
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,84 @@
package client
import (
"github.com/frostbyte73/core"
"github.com/livekit/livekit-server/pkg/rtc/datatrack"
"github.com/livekit/protocol/livekit"
"github.com/livekit/protocol/logger"
"go.uber.org/atomic"
)
type DataTrackRemote struct {
publisherIdentity livekit.ParticipantIdentity
publisherID livekit.ParticipantID
handle uint16
trackID livekit.TrackID
logger logger.Logger
numReceivedPackets atomic.Uint32
closed core.Fuse
}
func NewDataTrackRemote(
publisherIdentity livekit.ParticipantIdentity,
publisherID livekit.ParticipantID,
handle uint16,
trackID livekit.TrackID,
logger logger.Logger,
) *DataTrackRemote {
logger.Infow(
"creating data track remote",
"publisherIdentity", publisherIdentity,
"publisherID", publisherID,
"handle", handle,
"trackID", trackID,
)
return &DataTrackRemote{
publisherIdentity: publisherIdentity,
publisherID: publisherID,
handle: handle,
trackID: trackID,
logger: logger,
}
}
func (d *DataTrackRemote) Close() {
d.logger.Infow(
"closing data track remote",
"publisherIdentity", d.publisherIdentity,
"publisherID", d.publisherID,
"handle", d.handle,
"trackID", d.trackID,
)
d.closed.Break()
}
func (d *DataTrackRemote) Handle() uint16 {
return d.handle
}
func (d *DataTrackRemote) ID() livekit.TrackID {
return d.trackID
}
func (d *DataTrackRemote) PacketReceived(packet *datatrack.Packet) {
if d.closed.IsBroken() {
return
}
valid := len(packet.Payload) != 0
for i := range packet.Payload {
if packet.Payload[i] != byte(255-i) {
valid = false
break
}
}
if valid {
d.numReceivedPackets.Inc()
}
}
func (d *DataTrackRemote) NumReceivedPackets() uint32 {
return d.numReceivedPackets.Load()
}
@@ -0,0 +1,79 @@
// Copyright 2023 LiveKit, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package client
import (
"context"
"math/rand"
"time"
"github.com/livekit/livekit-server/pkg/rtc/datatrack"
"github.com/livekit/livekit-server/pkg/rtc/types"
"github.com/livekit/protocol/logger"
)
type dataTrackWriter struct {
ctx context.Context
cancel context.CancelFunc
handle uint16
transport types.DataTrackTransport
}
func NewDataTrackWriter(ctx context.Context, handle uint16, transport types.DataTrackTransport) TrackWriter {
ctx, cancel := context.WithCancel(ctx)
return &dataTrackWriter{
ctx: ctx,
cancel: cancel,
handle: handle,
transport: transport,
}
}
func (d *dataTrackWriter) Start() error {
go d.writeFrames()
return nil
}
func (d *dataTrackWriter) Stop() {
d.cancel()
}
func (d *dataTrackWriter) writeFrames() {
seqNum := uint16(0)
frameNum := uint16(0)
for {
select {
case <-d.ctx.Done():
return
default:
packets := datatrack.GenerateRawDataPackets(d.handle, seqNum, frameNum, 1, rand.Intn(2048)+1, 100*time.Millisecond)
for _, packet := range packets {
if err := d.transport.SendDataTrackMessage(packet); err != nil {
logger.Errorw("could not send data track packet", err)
}
}
if len(packets) != 0 {
var lastPacket datatrack.Packet
if err := lastPacket.Unmarshal(packets[len(packets)-1]); err == nil {
seqNum = lastPacket.SequenceNumber + 1
frameNum = lastPacket.FrameNumber + 1
}
}
time.Sleep(100 * time.Millisecond)
}
}
}
+16 -12
View File
@@ -26,13 +26,18 @@ import (
"github.com/pion/webrtc/v4/pkg/media/ivfreader"
"github.com/pion/webrtc/v4/pkg/media/oggreader"
"github.com/livekit/livekit-server/pkg/sfu/mime"
"github.com/livekit/protocol/codecs/mime"
"github.com/livekit/protocol/logger"
)
type TrackWriter interface {
Start() error
Stop()
}
// Writes a file to an RTP track.
// makes it easier to debug and create RTP streams
type TrackWriter struct {
type trackWriter struct {
ctx context.Context
cancel context.CancelFunc
track *webrtc.TrackLocalStaticSample
@@ -45,9 +50,9 @@ type TrackWriter struct {
h264 *h264reader.H264Reader
}
func NewTrackWriter(ctx context.Context, track *webrtc.TrackLocalStaticSample, filePath string) *TrackWriter {
func NewTrackWriter(ctx context.Context, track *webrtc.TrackLocalStaticSample, filePath string) TrackWriter {
ctx, cancel := context.WithCancel(ctx)
return &TrackWriter{
return &trackWriter{
ctx: ctx,
cancel: cancel,
track: track,
@@ -56,7 +61,7 @@ func NewTrackWriter(ctx context.Context, track *webrtc.TrackLocalStaticSample, f
}
}
func (w *TrackWriter) Start() error {
func (w *trackWriter) Start() error {
if w.filePath == "" {
go w.writeNull()
return nil
@@ -95,11 +100,11 @@ func (w *TrackWriter) Start() error {
return nil
}
func (w *TrackWriter) Stop() {
func (w *trackWriter) Stop() {
w.cancel()
}
func (w *TrackWriter) writeNull() {
func (w *trackWriter) writeNull() {
defer w.onWriteComplete()
sample := media.Sample{Data: []byte{0x0, 0xff, 0xff, 0xff, 0xff}, Duration: 30 * time.Millisecond}
h264Sample := media.Sample{Data: []byte{0x00, 0x00, 0x00, 0x01, 0x7, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x8, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x5, 0xff, 0xff, 0xff, 0xff}, Duration: 30 * time.Millisecond}
@@ -117,7 +122,7 @@ func (w *TrackWriter) writeNull() {
}
}
func (w *TrackWriter) writeOgg() {
func (w *trackWriter) writeOgg() {
// Keep track of last granule, the difference is the amount of samples in the buffer
var lastGranule uint64
for {
@@ -150,7 +155,7 @@ func (w *TrackWriter) writeOgg() {
}
}
func (w *TrackWriter) writeVP8() {
func (w *trackWriter) writeVP8() {
// Send our video file frame at a time. Pace our sending such that we send it at the same speed it should be played back as.
// This isn't required since the video is timestamped, but we will such much higher loss if we send all at once.
sleepTime := time.Millisecond * time.Duration((float32(w.ivfheader.TimebaseNumerator)/float32(w.ivfheader.TimebaseDenominator))*1000)
@@ -178,10 +183,9 @@ func (w *TrackWriter) writeVP8() {
}
}
func (w *TrackWriter) writeH264() {
func (w *trackWriter) writeH264() {
// TODO: this is harder
}
func (w *TrackWriter) onWriteComplete() {
func (w *trackWriter) onWriteComplete() {
}