rework needed
This commit is contained in:
@@ -3,10 +3,7 @@ package audiodriver
|
||||
import (
|
||||
"context"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"io"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/pion/mediadevices/pkg/io/audio"
|
||||
"github.com/pion/mediadevices/pkg/prop"
|
||||
@@ -24,46 +21,39 @@ const BufferSize = 512
|
||||
const BitsPerByte = 8
|
||||
|
||||
type WavFIFODriver struct {
|
||||
FIFOFile string
|
||||
f *os.File
|
||||
waveHeader *WavHeader
|
||||
PCM <-chan [BufferSize]byte
|
||||
WaveHeader <-chan *WavHeader
|
||||
closed <-chan struct{}
|
||||
cancel func()
|
||||
}
|
||||
|
||||
func New(fifoname string) *WavFIFODriver {
|
||||
return &WavFIFODriver{
|
||||
FIFOFile: fifoname,
|
||||
}
|
||||
func New() *WavFIFODriver {
|
||||
return &WavFIFODriver{}
|
||||
}
|
||||
|
||||
func (w *WavFIFODriver) Open() error {
|
||||
defer logrus.Debug("device opened")
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
w.closed = ctx.Done()
|
||||
w.cancel = cancel
|
||||
|
||||
f, err := os.Open(w.FIFOFile)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
w.f = f
|
||||
w.waveHeader = &WavHeader{}
|
||||
return w.waveHeader.Parse(f)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (w *WavFIFODriver) Close() error {
|
||||
defer w.cancel()
|
||||
return w.f.Close()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (w *WavFIFODriver) Properties() []prop.Media {
|
||||
waveHeader := <-w.WaveHeader
|
||||
logrus.Debugf("wave header: %v", waveHeader)
|
||||
return []prop.Media{
|
||||
{
|
||||
Audio: prop.Audio{
|
||||
SampleRate: int(w.waveHeader.SampleRate),
|
||||
ChannelCount: int(w.waveHeader.NumChannels),
|
||||
Latency: time.Millisecond * time.Duration(BufferSize) / time.Duration(w.waveHeader.SampleRate) / time.Duration(w.waveHeader.NumChannels),
|
||||
SampleRate: int(waveHeader.SampleRate),
|
||||
ChannelCount: int(waveHeader.NumChannels),
|
||||
Latency: waveHeader.GetLatnecy(),
|
||||
IsFloat: false, // just 8bit or 16bit with qemu
|
||||
IsBigEndian: false, // qemu should be little endian
|
||||
IsInterleaved: true,
|
||||
@@ -73,46 +63,18 @@ func (w *WavFIFODriver) Properties() []prop.Media {
|
||||
}
|
||||
|
||||
func (w *WavFIFODriver) AudioRecord(p prop.Media) (audio.Reader, error) {
|
||||
logrus.Debugf("wave header: %v", w.waveHeader)
|
||||
offset := FmtHeaderOffset + FmtHeaderIDSize + FmtHeaderChunkSizeSize + int64(w.waveHeader.Size) + DataChunkIDSize + DataChunkSizeSize
|
||||
if _, err := w.f.Seek(
|
||||
offset,
|
||||
io.SeekStart,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var pcm <-chan [BufferSize]byte
|
||||
go func() {
|
||||
samples := make(chan [BufferSize]byte, BufferSize)
|
||||
defer close(samples)
|
||||
|
||||
pcm = samples
|
||||
for {
|
||||
var b [BufferSize]byte
|
||||
if _, err := w.f.Read(b[:]); err != nil {
|
||||
if errors.Is(err, io.EOF) {
|
||||
return
|
||||
}
|
||||
logrus.Errorf("read audio stream error: %v", err)
|
||||
continue
|
||||
}
|
||||
samples <- b
|
||||
}
|
||||
}()
|
||||
|
||||
reader := func() (wave.Audio, func(), error) {
|
||||
select {
|
||||
case <-w.closed:
|
||||
return nil, func() {}, io.EOF
|
||||
case pcmData, ok := <-pcm:
|
||||
case pcmData, ok := <-w.PCM:
|
||||
logrus.Debug("got %d bytes pcm data", len(pcmData))
|
||||
if !ok {
|
||||
return nil, func() {}, io.ErrClosedPipe
|
||||
}
|
||||
|
||||
a := wave.NewInt16Interleaved(wave.ChunkInfo{
|
||||
Len: BufferSize / int(w.waveHeader.BitsPerSample/BitsPerByte),
|
||||
Len: BufferSize / int(p.SampleSize/BitsPerByte),
|
||||
Channels: p.ChannelCount,
|
||||
SamplingRate: p.SampleRate,
|
||||
})
|
||||
|
@@ -3,8 +3,10 @@ package audiodriver
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"io"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Skip riff header and `fmt ` just 16 bytes
|
||||
@@ -25,8 +27,18 @@ type WavHeader struct {
|
||||
BitsPerSample uint16
|
||||
}
|
||||
|
||||
func (w *WavHeader) Parse(f io.ReadSeeker) error {
|
||||
if _, err := f.Seek(FmtHeaderOffset, io.SeekStart); err != nil {
|
||||
func NewHeader(f io.Reader) (*WavHeader, error) {
|
||||
w := &WavHeader{}
|
||||
if err := w.Parse(f); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return w, nil
|
||||
}
|
||||
|
||||
func (w *WavHeader) Parse(f io.Reader) error {
|
||||
// skip headers
|
||||
var headers [FmtHeaderOffset]byte
|
||||
if _, err := f.Read(headers[:]); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -76,10 +88,19 @@ func (w *WavHeader) Parse(f io.ReadSeeker) error {
|
||||
w.BlockAlign = binary.LittleEndian.Uint16(ba[:])
|
||||
|
||||
var bps [2]byte
|
||||
if _, err := f.Read(ba[:]); err != nil {
|
||||
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() time.Duration {
|
||||
return time.Millisecond * time.Duration(BufferSize) / time.Duration(w.SampleRate) / time.Duration(w.NumChannels)
|
||||
}
|
||||
|
@@ -1,9 +1,11 @@
|
||||
package webrtcconnection
|
||||
|
||||
import (
|
||||
"git.sense-t.eu.org/ACE/ace/servers/qemuserver"
|
||||
"github.com/pion/mediadevices"
|
||||
"github.com/pion/mediadevices/pkg/codec/opus"
|
||||
"github.com/pion/mediadevices/pkg/codec/x264"
|
||||
"github.com/pion/mediadevices/pkg/driver"
|
||||
"github.com/pion/webrtc/v3"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
@@ -14,6 +16,7 @@ type Connection struct {
|
||||
option *Options
|
||||
api *webrtc.API
|
||||
stream mediadevices.MediaStream
|
||||
QEMU *qemuserver.Server
|
||||
}
|
||||
|
||||
func New(o *Options) (*Connection, error) {
|
||||
@@ -30,6 +33,17 @@ func New(o *Options) (*Connection, error) {
|
||||
|
||||
connection.api = webrtc.NewAPI(webrtc.WithMediaEngine(me))
|
||||
|
||||
logrus.Debug("list devices:")
|
||||
logrus.Debug("------")
|
||||
devices := driver.GetManager().Query(func(d driver.Driver) bool { return true })
|
||||
for _, device := range devices {
|
||||
logrus.Debug(device.ID())
|
||||
logrus.Debug(device.Info())
|
||||
logrus.Debug(device.Properties())
|
||||
logrus.Debug(device.Status())
|
||||
logrus.Debug("------")
|
||||
}
|
||||
|
||||
s, err := mediadevices.GetUserMedia(mediadevices.MediaStreamConstraints{
|
||||
Video: func(mtc *mediadevices.MediaTrackConstraints) {},
|
||||
Audio: func(mtc *mediadevices.MediaTrackConstraints) {},
|
||||
@@ -44,7 +58,7 @@ func New(o *Options) (*Connection, error) {
|
||||
}
|
||||
|
||||
func (c *Connection) Regist(offer *webrtc.SessionDescription) (*webrtc.SessionDescription, error) {
|
||||
logrus.Debug("received offer ", offer.Type.String())
|
||||
logrus.Debug("received offer ", offer)
|
||||
|
||||
rtc, err := c.api.NewPeerConnection(webrtc.Configuration{
|
||||
ICEServers: []webrtc.ICEServer{
|
||||
@@ -80,7 +94,7 @@ func (c *Connection) Regist(offer *webrtc.SessionDescription) (*webrtc.SessionDe
|
||||
}
|
||||
}
|
||||
|
||||
rtc.OnDataChannel(dataChannel)
|
||||
rtc.OnDataChannel(c.dataChannel)
|
||||
|
||||
if err := rtc.SetRemoteDescription(*offer); err != nil {
|
||||
return nil, err
|
||||
|
@@ -4,15 +4,14 @@ import (
|
||||
"encoding/json"
|
||||
"time"
|
||||
|
||||
"git.sense-t.eu.org/ACE/ace/servers/qemuserver"
|
||||
"github.com/pion/webrtc/v3"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func dataChannel(d *webrtc.DataChannel) {
|
||||
func (c *Connection) dataChannel(d *webrtc.DataChannel) {
|
||||
d.OnOpen(func() {
|
||||
for {
|
||||
status := qemuserver.GetStatus().String()
|
||||
status := c.QEMU.GetStatus().String()
|
||||
currentTime := time.Now().UnixMilli()
|
||||
|
||||
b, err := json.Marshal(map[string]any{
|
||||
@@ -40,7 +39,7 @@ func dataChannel(d *webrtc.DataChannel) {
|
||||
if !msg.IsString {
|
||||
return
|
||||
}
|
||||
if err := qemuserver.SendEvent(msg.Data); err != nil {
|
||||
if err := c.QEMU.SendEvent(msg.Data); err != nil {
|
||||
logrus.Errorf(
|
||||
"cannot parse message from '%s-%d' to qemu controll event: %v",
|
||||
d.Label(), *d.ID(), err,
|
||||
|
Reference in New Issue
Block a user