-
Notifications
You must be signed in to change notification settings - Fork 8
/
nanowriter.go
102 lines (87 loc) · 2.58 KB
/
nanowriter.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
package main
import (
"bytes"
"encoding/binary"
"io"
//"fmt"
"strconv"
"time"
cm "github.com/danielpaulus/quicktime_video_hack/screencapture/coremedia"
"go.nanomsg.org/mangos/v3"
// register transports
_ "go.nanomsg.org/mangos/v3/transport/all"
)
var startCode = []byte{00, 00, 00, 01}
//ZMQWriter writes nalus into a file using 0x00000001 as a separator (h264 ANNEX B) and raw pcm audio into a wav file
type NanoWriter struct {
socket mangos.Socket
buffer bytes.Buffer
fh io.Writer
}
func NewNanoWriter( socket mangos.Socket ) NanoWriter {
return NanoWriter{ socket: socket }
}
func NewFileWriter( fh io.Writer ) NanoWriter {
return NanoWriter{ fh: fh }
}
//Consume writes PPS and SPS as well as sample bufs into a annex b .h264 file and audio samples into a wav file
func (avfw NanoWriter) Consume(buf cm.CMSampleBuffer) error {
if buf.MediaType == cm.MediaTypeSound {
return avfw.consumeAudio(buf)
}
return avfw.consumeVideo(buf)
}
func (self NanoWriter) Stop() {}
func (self NanoWriter) consumeVideo(buf cm.CMSampleBuffer) error {
if buf.HasFormatDescription {
err := self.writeNalu(buf.FormatDescription.PPS)
if err != nil {
return err
}
err = self.writeNalu(buf.FormatDescription.SPS)
if err != nil {
return err
}
}
if !buf.HasSampleData() {
return nil
}
return self.writeNalus(buf.SampleData)
}
func (self NanoWriter) writeNalus(bytes []byte) error {
slice := bytes
for len(slice) > 0 {
length := binary.BigEndian.Uint32(slice)
err := self.writeNalu(slice[4 : length+4])
if err != nil {
return err
}
slice = slice[length+4:]
}
return nil
}
func (self NanoWriter) writeNalu(naluBytes []byte) error {
now := strconv.FormatInt( time.Now().UnixNano()/1000000, 10 )
json := "{\"nalBytes\":" + strconv.Itoa( len( naluBytes ) + 4 ) + ",\"time\":" + now + "}";
var jsonLen uint16 = uint16( len( json ) )
binary.Write( &self.buffer, binary.LittleEndian, jsonLen )
self.buffer.Write( []byte( json ) )
_, err := self.buffer.Write(startCode)
if err != nil {
return err
}
_, err = self.buffer.Write(naluBytes)
if err != nil {
return err
}
if self.fh == nil {
self.socket.Send( self.buffer.Bytes() )
} else {
self.fh.Write( self.buffer.Bytes() )
}
self.buffer.Reset()
return nil
}
func (self NanoWriter) consumeAudio(buffer cm.CMSampleBuffer) error {
return nil
}