driver done
This commit is contained in:
		
							
								
								
									
										92
									
								
								drivers/audio/wavfifo.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										92
									
								
								drivers/audio/wavfifo.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,92 @@ | ||||
| package audio | ||||
|  | ||||
| import ( | ||||
| 	"context" | ||||
| 	"encoding/binary" | ||||
| 	"io" | ||||
|  | ||||
| 	"github.com/pion/mediadevices/pkg/io/audio" | ||||
| 	"github.com/pion/mediadevices/pkg/prop" | ||||
| 	"github.com/pion/mediadevices/pkg/wave" | ||||
| 	"github.com/sirupsen/logrus" | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	DataChunkIDSize   = 4 | ||||
| 	DataChunkSizeSize = 4 | ||||
| ) | ||||
|  | ||||
| // BufferSize for pcm bytes | ||||
| const BitsPerByte = 8 | ||||
|  | ||||
| type PCMStreamDriver struct { | ||||
| 	PCM               <-chan []byte | ||||
| 	BufferSizeByBytes uint16 | ||||
| 	WaveHeader        *WavHeader | ||||
| 	closed            <-chan struct{} | ||||
| 	cancel            func() | ||||
| } | ||||
|  | ||||
| func (w *PCMStreamDriver) Open() error { | ||||
| 	ctx, cancel := context.WithCancel(context.Background()) | ||||
| 	w.closed = ctx.Done() | ||||
| 	w.cancel = cancel | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (w *PCMStreamDriver) Close() error { | ||||
| 	w.cancel() | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (w *PCMStreamDriver) Properties() []prop.Media { | ||||
| 	logrus.Debugf("wave header: %v", w.WaveHeader) | ||||
| 	return []prop.Media{ | ||||
| 		{ | ||||
| 			Audio: prop.Audio{ | ||||
| 				SampleRate:    int(w.WaveHeader.SampleRate), | ||||
| 				ChannelCount:  int(w.WaveHeader.NumChannels), | ||||
| 				SampleSize:    int(w.WaveHeader.BitsPerSample), | ||||
| 				Latency:       w.WaveHeader.GetLatnecy(w.BufferSizeByBytes), | ||||
| 				IsFloat:       false, // just 8bit or 16bit with qemu | ||||
| 				IsBigEndian:   false, // qemu should be little endian | ||||
| 				IsInterleaved: true, | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (w *PCMStreamDriver) AudioRecord(p prop.Media) (audio.Reader, error) { | ||||
| 	logrus.Debug(p) | ||||
| 	chunkInfo := wave.ChunkInfo{ | ||||
| 		Len:          int(w.BufferSizeByBytes) / int(p.SampleSize/BitsPerByte), | ||||
| 		Channels:     p.ChannelCount, | ||||
| 		SamplingRate: p.SampleRate, | ||||
| 	} | ||||
|  | ||||
| 	reader := func() (wave.Audio, func(), error) { | ||||
| 		a := wave.NewInt16Interleaved(chunkInfo) | ||||
| 		select { | ||||
| 		case <-w.closed: | ||||
| 			return nil, func() {}, io.EOF | ||||
| 		case pcmData, ok := <-w.PCM: | ||||
| 			logrus.Debug("got %d bytes pcm data", len(pcmData)) | ||||
| 			if !ok { | ||||
| 				return nil, func() {}, io.ErrClosedPipe | ||||
| 			} | ||||
| 			copy(a.Data, bytesTo16BitSamples(pcmData[:])) | ||||
| 		} | ||||
| 		return a, func() {}, nil | ||||
| 	} | ||||
| 	return audio.ReaderFunc(reader), nil | ||||
| } | ||||
|  | ||||
| func bytesTo16BitSamples(b []byte) []int16 { | ||||
| 	samples := make([]int16, 0) | ||||
| 	for i := 0; i < len(b); i += 2 { | ||||
| 		sample := binary.LittleEndian.Uint16(b[i : i+1]) | ||||
| 		samples = append(samples, int16(sample)) | ||||
| 	} | ||||
| 	return samples | ||||
| } | ||||
							
								
								
									
										124
									
								
								drivers/audio/wavheader.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										124
									
								
								drivers/audio/wavheader.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,124 @@ | ||||
| package audio | ||||
|  | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"encoding/binary" | ||||
| 	"encoding/json" | ||||
| 	"errors" | ||||
| 	"io" | ||||
| 	"time" | ||||
| ) | ||||
|  | ||||
| // Skip riff header and `fmt ` just 16 bytes | ||||
| const ( | ||||
| 	FmtHeaderOffset        = 0x0c | ||||
| 	FmtHeaderIDSize        = 4 | ||||
| 	FmtHeaderChunkSizeSize = 4 | ||||
| 	FmtHeaderSizeDefault   = 16 | ||||
| ) | ||||
|  | ||||
| type WavHeader struct { | ||||
| 	ID            [4]byte | ||||
| 	Size          uint32 | ||||
| 	AudioFormat   uint16 | ||||
| 	NumChannels   uint16 | ||||
| 	SampleRate    uint32 | ||||
| 	ByteRate      uint32 | ||||
| 	BlockAlign    uint16 | ||||
| 	BitsPerSample uint16 | ||||
| } | ||||
|  | ||||
| func NewHeader(f io.Reader) (*WavHeader, error) { | ||||
| 	w := &WavHeader{} | ||||
| 	if err := w.Parse(f); err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return w, nil | ||||
| } | ||||
|  | ||||
| func DefaultHeader() *WavHeader { | ||||
| 	return &WavHeader{ | ||||
| 		Size:          uint32(FmtHeaderSizeDefault), | ||||
| 		AudioFormat:   1, | ||||
| 		NumChannels:   2, | ||||
| 		SampleRate:    48000, // opus only support 48kHz | ||||
| 		BlockAlign:    4, | ||||
| 		BitsPerSample: 16, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (w *WavHeader) Parse(f io.Reader) error { | ||||
| 	// skip headers | ||||
| 	var headers [FmtHeaderOffset]byte | ||||
| 	if _, err := f.Read(headers[:]); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	var id [4]byte | ||||
| 	if _, err := f.Read(id[:]); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	if bytes.Equal(id[:], []byte{'f', 'm', 't', '0'}[:]) { | ||||
| 		return errors.New("bad header") | ||||
| 	} | ||||
| 	w.ID = id | ||||
|  | ||||
| 	var size [4]byte | ||||
| 	if _, err := f.Read(size[:]); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	w.Size = binary.LittleEndian.Uint32(size[:]) | ||||
|  | ||||
| 	var af [2]byte | ||||
| 	if _, err := f.Read(af[:]); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	w.AudioFormat = binary.LittleEndian.Uint16(af[:]) | ||||
|  | ||||
| 	var nc [2]byte | ||||
| 	if _, err := f.Read(nc[:]); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	w.NumChannels = binary.LittleEndian.Uint16(nc[:]) | ||||
|  | ||||
| 	var sr [4]byte | ||||
| 	if _, err := f.Read(sr[:]); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	w.SampleRate = binary.LittleEndian.Uint32(sr[:]) | ||||
|  | ||||
| 	var br [4]byte | ||||
| 	if _, err := f.Read(br[:]); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	w.ByteRate = binary.LittleEndian.Uint32(br[:]) | ||||
|  | ||||
| 	var ba [2]byte | ||||
| 	if _, err := f.Read(ba[:]); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	w.BlockAlign = binary.LittleEndian.Uint16(ba[:]) | ||||
|  | ||||
| 	var bps [2]byte | ||||
| 	if _, err := f.Read(bps[:]); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	w.BitsPerSample = binary.LittleEndian.Uint16(bps[:]) | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (w *WavHeader) String() string { | ||||
| 	b, _ := json.Marshal(w) | ||||
| 	return string(b) | ||||
| } | ||||
|  | ||||
| func (w *WavHeader) GetLatnecy(bufferSizeByBytes uint16) time.Duration { | ||||
| 	bytesPerSample := w.BitsPerSample / BitsPerByte | ||||
| 	bufferLength := bufferSizeByBytes / bytesPerSample | ||||
|  | ||||
| 	return time.Second * | ||||
| 		time.Duration(bufferLength) / | ||||
| 		time.Duration(w.NumChannels) / | ||||
| 		time.Duration(w.SampleRate) | ||||
| } | ||||
							
								
								
									
										92
									
								
								drivers/video/ppm.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										92
									
								
								drivers/video/ppm.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,92 @@ | ||||
| package video | ||||
|  | ||||
| import ( | ||||
| 	"context" | ||||
| 	"image" | ||||
| 	"image/color" | ||||
| 	"io" | ||||
|  | ||||
| 	"github.com/pion/mediadevices/pkg/frame" | ||||
| 	"github.com/pion/mediadevices/pkg/io/video" | ||||
| 	"github.com/pion/mediadevices/pkg/prop" | ||||
| 	"github.com/sirupsen/logrus" | ||||
|  | ||||
| 	_ "github.com/jbuchbinder/gopnm" | ||||
| ) | ||||
|  | ||||
| const DefaultFPS float32 = 60.0 | ||||
|  | ||||
| type PPMStreamDriver struct { | ||||
| 	Height, Width int | ||||
| 	FPS           float32 | ||||
| 	PPMImage      <-chan io.ReadCloser | ||||
| 	closed        <-chan struct{} | ||||
| 	cancel        func() | ||||
| } | ||||
|  | ||||
| func (v *PPMStreamDriver) Open() error { | ||||
| 	defer logrus.Debug("device opened") | ||||
| 	ctx, cancel := context.WithCancel(context.Background()) | ||||
| 	v.closed = ctx.Done() | ||||
| 	v.cancel = cancel | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (v *PPMStreamDriver) Close() error { | ||||
| 	v.cancel() | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (v *PPMStreamDriver) Properties() []prop.Media { | ||||
| 	return []prop.Media{ | ||||
| 		{ | ||||
| 			Video: prop.Video{ | ||||
| 				Width:       v.Width, | ||||
| 				Height:      v.Height, | ||||
| 				FrameRate:   v.FPS, | ||||
| 				FrameFormat: frame.FormatYUYV, | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (v *PPMStreamDriver) VideoRecord(p prop.Media) (video.Reader, error) { | ||||
| 	r := video.ReaderFunc(func() (img image.Image, release func(), err error) { | ||||
| 		canvas := image.NewYCbCr( | ||||
| 			image.Rect(0, 0, p.Width, p.Height), | ||||
| 			image.YCbCrSubsampleRatio420, | ||||
| 		) | ||||
|  | ||||
| 		select { | ||||
| 		case <-v.closed: | ||||
| 			return nil, func() {}, io.EOF | ||||
| 		case ppmF, ok := <-v.PPMImage: | ||||
| 			if !ok { | ||||
| 				return nil, func() {}, io.ErrClosedPipe | ||||
| 			} | ||||
| 			defer ppmF.Close() | ||||
|  | ||||
| 			img, _, err := image.Decode(ppmF) | ||||
| 			if err != nil { | ||||
| 				return nil, func() {}, err | ||||
| 			} | ||||
|  | ||||
| 			// draw input image in middle of canvas | ||||
| 			offsetX := (canvas.Bounds().Dx() - img.Bounds().Dx()) / 2 | ||||
| 			offsetY := (canvas.Bounds().Dy() - img.Bounds().Dy()) / 2 | ||||
| 			for x := 0; x < img.Bounds().Dx(); x++ { | ||||
| 				for y := 0; y < img.Bounds().Dy(); y++ { | ||||
| 					r, g, b, _ := img.At(x, y).RGBA() | ||||
| 					Y, Cb, Cr := color.RGBToYCbCr(uint8(r), uint8(g), uint8(b)) | ||||
|  | ||||
| 					canvas.Y[canvas.YOffset(offsetX+x, offsetY+y)] = Y | ||||
| 					canvas.Cb[canvas.COffset(offsetX+x, offsetY+y)] = Cb | ||||
| 					canvas.Cr[canvas.COffset(offsetX+x, offsetY+y)] = Cr | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		return canvas, func() {}, nil | ||||
| 	}) | ||||
| 	return r, nil | ||||
| } | ||||
							
								
								
									
										2
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								go.mod
									
									
									
									
									
								
							| @@ -3,6 +3,7 @@ module git.sense-t.eu.org/ACE/ace | ||||
| go 1.19 | ||||
|  | ||||
| require ( | ||||
| 	github.com/jbuchbinder/gopnm v0.0.0-20220507095634-e31f54490ce0 | ||||
| 	github.com/pion/mediadevices v0.3.11 | ||||
| 	github.com/urfave/cli/v2 v2.11.2 | ||||
| ) | ||||
| @@ -50,7 +51,6 @@ require ( | ||||
| require ( | ||||
| 	github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect | ||||
| 	github.com/digitalocean/go-qemu v0.0.0-20220804221245-2002801203aa | ||||
| 	github.com/gin-contrib/static v0.0.1 | ||||
| 	github.com/gin-gonic/gin v1.8.1 | ||||
| 	github.com/pion/webrtc/v3 v3.1.43 | ||||
| 	github.com/russross/blackfriday/v2 v2.1.0 // indirect | ||||
|   | ||||
							
								
								
									
										19
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								go.sum
									
									
									
									
									
								
							| @@ -16,27 +16,20 @@ github.com/gen2brain/malgo v0.10.35/go.mod h1:zHSUNZAXfCeNsZou0RtQ6Zk7gDYLIcKOrU | ||||
| github.com/gen2brain/shm v0.0.0-20200228170931-49f9650110c5/go.mod h1:uF6rMu/1nvu+5DpiRLwusA6xB8zlkNoGzKn8lmYONUo= | ||||
| github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= | ||||
| github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= | ||||
| github.com/gin-contrib/static v0.0.1 h1:JVxuvHPuUfkoul12N7dtQw7KRn/pSMq7Ue1Va9Swm1U= | ||||
| github.com/gin-contrib/static v0.0.1/go.mod h1:CSxeF+wep05e0kCOsqWdAWbSszmc31zTIbD8TvWl7Hs= | ||||
| github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= | ||||
| github.com/gin-gonic/gin v1.8.1 h1:4+fr/el88TOO3ewCmQr8cx/CtZ/umlIRIs5M4NTNjf8= | ||||
| github.com/gin-gonic/gin v1.8.1/go.mod h1:ji8BvRH1azfM+SYow9zQ6SZMvR8qOMZHmsCuWR9tTTk= | ||||
| github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A= | ||||
| github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= | ||||
| github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= | ||||
| github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU= | ||||
| github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs= | ||||
| github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= | ||||
| github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho= | ||||
| github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA= | ||||
| github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= | ||||
| github.com/go-playground/validator/v10 v10.10.0 h1:I7mrTYv78z8k8VXa/qJlOlEXn/nBh+BF8dHX5nt/dr0= | ||||
| github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos= | ||||
| github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= | ||||
| github.com/goccy/go-json v0.9.7 h1:IcB+Aqpx/iMHu5Yooh7jEzJk1JZ7Pjtmys2ukPr7EeM= | ||||
| github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= | ||||
| github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= | ||||
| github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= | ||||
| github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= | ||||
| github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= | ||||
| github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= | ||||
| @@ -54,8 +47,9 @@ github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/ | ||||
| github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= | ||||
| github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= | ||||
| github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= | ||||
| github.com/jbuchbinder/gopnm v0.0.0-20220507095634-e31f54490ce0 h1:9GwwkVzUn1vRWAQ8GRu7UOaoM+FZGnvw88DsjyiqfXc= | ||||
| github.com/jbuchbinder/gopnm v0.0.0-20220507095634-e31f54490ce0/go.mod h1:6U0E76+sB1jTuSSXJjePtLd44vExeoYThOWgOoXo3x8= | ||||
| github.com/jezek/xgb v0.0.0-20210312150743-0e0f116e1240/go.mod h1:3P4UH/k22rXyHIJD2w4h2XMqPX4Of/eySEZq9L6wqc4= | ||||
| github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= | ||||
| github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= | ||||
| github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= | ||||
| github.com/kbinani/screenshot v0.0.0-20210720154843-7d3a670d8329/go.mod h1:2VPVQDR4wO7KXHwP+DAypEy67rXf+okUx2zjgpCxZw4= | ||||
| @@ -67,17 +61,14 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= | ||||
| github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= | ||||
| github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= | ||||
| github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= | ||||
| github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= | ||||
| github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= | ||||
| github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= | ||||
| github.com/lxn/win v0.0.0-20210218163916-a377121e959e/go.mod h1:KxxjdtRkfNoYDCUP5ryK7XJJNTnpC8atvtmTheChOtk= | ||||
| github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= | ||||
| github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= | ||||
| github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= | ||||
| github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= | ||||
| github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= | ||||
| github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= | ||||
| github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= | ||||
| github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= | ||||
| github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= | ||||
| github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= | ||||
| @@ -147,15 +138,12 @@ github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0 | ||||
| github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= | ||||
| github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= | ||||
| github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= | ||||
| github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= | ||||
| github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= | ||||
| github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= | ||||
| github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= | ||||
| github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= | ||||
| github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= | ||||
| github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= | ||||
| github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M= | ||||
| github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= | ||||
| github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= | ||||
| github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= | ||||
| github.com/urfave/cli/v2 v2.11.2 h1:FVfNg4m3vbjbBpLYxW//WjxUoHvJ9TlppXcqY9Q9ZfA= | ||||
| @@ -204,7 +192,6 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w | ||||
| golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20201018230417-eeed37f84f13/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| @@ -225,7 +212,6 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc | ||||
| golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= | ||||
| golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= | ||||
| golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= | ||||
| golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= | ||||
| golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= | ||||
| golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= | ||||
| golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= | ||||
| @@ -259,7 +245,6 @@ gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMy | ||||
| gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= | ||||
| gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | ||||
| gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | ||||
| gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | ||||
| gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | ||||
| gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= | ||||
| gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= | ||||
|   | ||||
		Reference in New Issue
	
	Block a user