Skip to content

Commit 559676a

Browse files
committed
issue #222: fix audio stream stutter btween ovelay TS file;
1. let continuity_counter continually between overlay ts; 2. copy audio data when transcoding ts;
1 parent 9b475d9 commit 559676a

File tree

2 files changed

+114
-2
lines changed

2 files changed

+114
-2
lines changed

platform/transcript.go

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"github.com/ossrs/go-oryx-lib/errors"
2222
ohttp "github.com/ossrs/go-oryx-lib/http"
2323
"github.com/ossrs/go-oryx-lib/logger"
24+
2425
// Use v8 because we use Go 1.16+, while v9 requires Go 1.18+
2526
"github.com/go-redis/redis/v8"
2627
"github.com/google/uuid"
@@ -1295,6 +1296,9 @@ type TranscriptSegment struct {
12951296
// Whether user clear the ASR text of this segment.
12961297
UserClearASR bool `json:"uca,omitempty"`
12971298

1299+
// The map that host the pid -> last cc
1300+
OverlayTSLastCC map[uint16]uint8 `json:"start_cc,omitempty"`
1301+
12981302
// The cost to transcode the TS file to audio file.
12991303
CostExtractAudio time.Duration `json:"eac,omitempty"`
13001304
// The cost to do ASR, converting speech to text.
@@ -1402,6 +1406,16 @@ func (v *TranscriptQueue) first() *TranscriptSegment {
14021406
return v.Segments[0]
14031407
}
14041408

1409+
func (v *TranscriptQueue) find_by(seq_no uint64) *TranscriptSegment {
1410+
for i := len(v.Segments) - 1; i >= 0; i-- {
1411+
if v.Segments[i].OverlayFile.SeqNo == seq_no {
1412+
return v.Segments[i]
1413+
}
1414+
}
1415+
1416+
return nil
1417+
}
1418+
14051419
func (v *TranscriptQueue) clearSubtitle(tsid string) error {
14061420
v.lock.Lock()
14071421
defer v.lock.Unlock()
@@ -1594,7 +1608,7 @@ func (v *TranscriptTask) OnTsSegment(ctx context.Context, msg *SrsOnHlsObject) e
15941608
func() {
15951609
// We must not update the queue, when persistence goroutine is working.
15961610
v.lock.Lock()
1597-
v.lock.Unlock()
1611+
defer v.lock.Unlock()
15981612

15991613
v.LiveQueue.enqueue(&TranscriptSegment{
16001614
Msg: msg.Msg,
@@ -1978,7 +1992,7 @@ func (v *TranscriptTask) DriveFixQueue(ctx context.Context) error {
19781992
args = append(args, strings.Fields(videoCodecParams)...)
19791993
// Generate other parameters for FFmpeg.
19801994
args = append(args, []string{
1981-
"-c:a", "aac",
1995+
"-c:a", "copy",
19821996
"-copyts", // To keep the pts not changed.
19831997
"-y", overlayFile.File,
19841998
}...)
@@ -2004,6 +2018,21 @@ func (v *TranscriptTask) DriveFixQueue(ctx context.Context) error {
20042018
}
20052019
overlayFile.Size = uint64(stats.Size())
20062020

2021+
// recaculate the continuity_counter of overlayFile
2022+
// 1. get previous segment in overlayQueue
2023+
// 2. adjust current ts segment's continuity_counter
2024+
// 2. change segment.OverlayTSLastCC
2025+
previous_ts_cc := map[uint16]uint8{}
2026+
if previous_segment := v.OverlayQueue.find_by(overlayFile.SeqNo - 1); previous_segment != nil {
2027+
previous_ts_cc = previous_segment.OverlayTSLastCC
2028+
}
2029+
2030+
if cc, err := overlayFile.AdjustCC(previous_ts_cc); err != nil {
2031+
logger.Wf(ctx, "Error when Adjust Overlay TS file %v", overlayFile.File)
2032+
} else {
2033+
segment.OverlayTSLastCC = cc
2034+
}
2035+
20072036
// Dequeue the segment from live queue and attach to asr queue.
20082037
func() {
20092038
v.lock.Lock()

platform/utils.go

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1129,6 +1129,89 @@ func (v *TsFile) String() string {
11291129
)
11301130
}
11311131

1132+
func (v *TsFile) AdjustCC(cc map[uint16]uint8) (map[uint16]uint8, error) {
1133+
const BUF_SIZE = 188
1134+
tmp_file_name := v.File + ".tmp"
1135+
1136+
err := func() error {
1137+
file, err := os.Open(v.File)
1138+
if err != nil {
1139+
return err
1140+
}
1141+
defer file.Close()
1142+
1143+
tmp_file, err := os.Create(tmp_file_name)
1144+
if err != nil {
1145+
return err
1146+
}
1147+
defer tmp_file.Close()
1148+
1149+
buffer := make([]byte, BUF_SIZE)
1150+
1151+
for {
1152+
bytes_read, err := file.Read(buffer)
1153+
if err != nil {
1154+
if err == io.EOF {
1155+
return nil
1156+
}
1157+
1158+
return err
1159+
}
1160+
1161+
if bytes_read != BUF_SIZE {
1162+
return errors.Errorf("Read TS packet with size %v", bytes_read)
1163+
}
1164+
1165+
if sync_byte := buffer[0]; sync_byte != 0x47 {
1166+
return errors.Errorf("TS packet sync byte is not 0x47")
1167+
}
1168+
1169+
// transport_error_indicator := uint8(buffer[1] & 0x80 >> 7)
1170+
// payload_unit_start_indicator := uint8(buffer[1] & 0x40 >> 6)
1171+
// transport_priority := uint8(buffer[1] & 0x20 >> 5)
1172+
pid := uint16(buffer[1]&0x1f)<<8 + uint16(buffer[2])
1173+
// transport_scrambling_control := uint8(buffer[3] & 0xC0 >> 6)
1174+
// adaptation_field_control := uint8(buffer[3] & 0x30 >> 4)
1175+
continuity_counter := uint8(buffer[3] & 0x0f)
1176+
1177+
if pid == 256 || pid == 257 {
1178+
if counter, hasKey := cc[pid]; hasKey {
1179+
if continuity_counter != counter+1 {
1180+
continuity_counter = counter + 1
1181+
if continuity_counter > 15 {
1182+
continuity_counter = 0
1183+
}
1184+
1185+
buffer[3] = (buffer[3] & 0xf0) | continuity_counter
1186+
}
1187+
1188+
cc[pid] = continuity_counter
1189+
} else {
1190+
cc[pid] = continuity_counter
1191+
}
1192+
}
1193+
1194+
if _, err := tmp_file.Write(buffer); err != nil {
1195+
return err
1196+
}
1197+
}
1198+
}()
1199+
1200+
if err != nil {
1201+
return nil, err
1202+
}
1203+
1204+
if _, err := os.Stat(tmp_file_name); err != nil {
1205+
return nil, err
1206+
}
1207+
1208+
if err := os.Rename(tmp_file_name, v.File); err != nil {
1209+
return nil, err
1210+
}
1211+
1212+
return cc, nil
1213+
}
1214+
11321215
// M3u8VoDArtifact is a HLS VoD object. Because each Dvr/Vod/RecordM3u8Stream might be DVR to many VoD file,
11331216
// each is an M3u8VoDArtifact. For example, when user publish live/livestream, there is a Dvr/Vod/RecordM3u8Stream and
11341217
// M3u8VoDArtifact, then user unpublish stream and after some seconds a VoD file is generated by M3u8VoDArtifact. Then

0 commit comments

Comments
 (0)