Add working Segment duration

This commit is contained in:
DataHoarder 2022-04-20 22:49:15 +02:00
parent 97e71357be
commit 6511f2e9c1
Signed by: DataHoarder
SSH key fingerprint: SHA256:OLTRf6Fl87G52SiR7sWLGNzlJt4WOX+tfI2yxo0z7xk
3 changed files with 46 additions and 17 deletions

View file

@ -44,6 +44,10 @@ func (e *FrameEncoder) GetInputSize() int {
return int(e.handle.input_packet_size)
}
func (e *FrameEncoder) GetSamplesPerPacket() int {
return int(e.handle.frames_per_packet)
}
func (e *FrameEncoder) WritePacket(pcm []byte) []byte {
output := make([]byte, int(e.handle.output_max_packet_size))
outBytes := C.alac_encoder_write(&e.handle, (*C.uchar)(unsafe.Pointer(&pcm[0])), C.int(len(pcm)), (*C.uchar)(unsafe.Pointer(&output[0])))

57
mp4.go
View file

@ -8,12 +8,16 @@ import (
)
type FormatEncoder struct {
encoder *FrameEncoder
writer io.Writer
buffer []byte
segmentDuration int64
trackId uint32
seqNumber uint32
encoder *FrameEncoder
writer io.Writer
sampleRate int
buffer []byte
outputBuffer [][]byte
segmentDuration time.Duration
samplesPerPacket int
packetsWritten int
trackId uint32
seqNumber uint32
}
type alacBox struct {
@ -58,13 +62,16 @@ func NewFormatEncoder(writer io.Writer, sampleRate, channels, bitDepth int, fast
e := &FormatEncoder{
encoder: NewFrameEncoder(sampleRate, channels, bitDepth, fastMode),
writer: writer,
segmentDuration: segmentDuration.Milliseconds(),
sampleRate: sampleRate,
segmentDuration: segmentDuration,
}
if e.encoder == nil {
return nil
}
e.samplesPerPacket = e.encoder.GetSamplesPerPacket()
init := mp4.CreateEmptyInit()
init.AddEmptyTrack(uint32(sampleRate), "audio", "en")
e.trackId = init.Moov.Mvhd.NextTrackID - 1
@ -84,21 +91,39 @@ func NewFormatEncoder(writer io.Writer, sampleRate, channels, bitDepth int, fast
}
func (e *FormatEncoder) outputPacket(packet []byte) {
//TODO: more frames
e.outputBuffer = append(e.outputBuffer, packet)
if time.Duration(float64(time.Second)*(float64(e.samplesPerPacket*len(e.outputBuffer))/float64(e.sampleRate))) >= e.segmentDuration {
e.outputSegment()
}
}
func (e *FormatEncoder) outputSegment() {
if len(e.outputBuffer) == 0 {
return
}
seg := mp4.NewMediaSegment()
frag, _ := mp4.CreateFragment(e.seqNumber, e.trackId)
seg.AddFragment(frag)
frag.AddFullSampleToTrack(mp4.FullSample{
Sample: mp4.Sample{
Dur: 4096, //TODO
Size: uint32(len(packet)),
},
DecodeTime: uint64(4096 * e.seqNumber),
Data: packet,
}, e.trackId)
for _, b := range e.outputBuffer {
frag.AddFullSampleToTrack(mp4.FullSample{
Sample: mp4.Sample{
Dur: uint32(e.samplesPerPacket),
Size: uint32(len(b)),
},
DecodeTime: uint64(e.samplesPerPacket * e.packetsWritten),
Data: b,
}, e.trackId)
e.packetsWritten++
}
seg.Encode(e.writer)
e.seqNumber++
e.outputBuffer = nil
}
func (e *FormatEncoder) Write(pcm []byte) {

View file

@ -30,7 +30,7 @@ func TestEncodeMP4(t *testing.T) {
}
defer o.Close()
encoder := NewFormatEncoder(o, 44100, 2, 16, false, time.Second)
encoder := NewFormatEncoder(o, 44100, 2, 16, false, time.Millisecond*100)
iterationSize := 65536
for len(data) > iterationSize {