From 8e506ffcf145c8a52b875ddef6f6e8d13660077b Mon Sep 17 00:00:00 2001 From: Yoshida Hiroshi Date: Mon, 6 Jan 2025 12:49:44 +0900 Subject: [PATCH 01/11] =?UTF-8?q?=E5=8F=97=E4=BF=A1=E3=81=97=E3=81=9F?= =?UTF-8?q?=E9=9F=B3=E5=A3=B0=E3=83=87=E3=83=BC=E3=82=BF=E3=82=92=20Ogg=20?= =?UTF-8?q?=E3=83=95=E3=82=A1=E3=82=A4=E3=83=AB=E3=81=A7=E5=87=BA=E5=8A=9B?= =?UTF-8?q?=E3=81=A7=E3=81=8D=E3=82=8B=E6=A9=9F=E8=83=BD=E3=82=92=E8=BF=BD?= =?UTF-8?q?=E5=8A=A0=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- amazon_transcribe_handler.go | 7 ++++-- config.go | 7 ++++++ config_example.ini | 4 ++++ handler.go | 45 +++++++++++++++++++++++++----------- packet_dump_handler.go | 2 +- service_handler.go | 2 +- speech_to_text_handler.go | 7 ++++-- test_handler.go | 2 +- 8 files changed, 56 insertions(+), 20 deletions(-) diff --git a/amazon_transcribe_handler.go b/amazon_transcribe_handler.go index adc73cc..737999f 100644 --- a/amazon_transcribe_handler.go +++ b/amazon_transcribe_handler.go @@ -96,10 +96,13 @@ func (h *AmazonTranscribeHandler) ResetRetryCount() int { return h.RetryCount } -func (h *AmazonTranscribeHandler) Handle(ctx context.Context, opusCh chan opusChannel) (*io.PipeReader, error) { +func (h *AmazonTranscribeHandler) Handle(ctx context.Context, opusCh chan opusChannel, header soraHeader) (*io.PipeReader, error) { at := NewAmazonTranscribe(h.Config, h.LanguageCode, int64(h.SampleRate), int64(h.ChannelCount)) - packetReader := opus2ogg(ctx, opusCh, h.SampleRate, h.ChannelCount, h.Config) + packetReader, err := opus2ogg(ctx, opusCh, h.SampleRate, h.ChannelCount, h.Config, header) + if err != nil { + return nil, err + } stream, err := at.Start(ctx, packetReader) if err != nil { diff --git a/config.go b/config.go index aeba0ad..cd138e8 100644 --- a/config.go +++ b/config.go @@ -65,6 +65,9 @@ type Config struct { SampleRate int `ini:"audio_sample_rate"` ChannelCount int `ini:"audio_channel_count"` + EnableOggFileOutput bool `ini:"enable_ogg_file_output"` + OggDir string `ini:"ogg_dir"` + DumpFile string `ini:"dump_file"` LogDir string `ini:"log_dir"` @@ -173,6 +176,10 @@ func setDefaultsConfig(config *Config) { if config.RetryIntervalMs == 0 { config.RetryIntervalMs = DefaultRetryIntervalMs } + + if config.OggDir == "" { + config.OggDir = "." + } } func validateConfig(config *Config) error { diff --git a/config_example.ini b/config_example.ini index b9578a3..6493c2f 100644 --- a/config_example.ini +++ b/config_example.ini @@ -55,6 +55,10 @@ retry_interval_ms = 100 # aws の場合は IsPartial が false, gcp の場合は IsFinal が true の場合の最終的な結果のみを返す指定 final_result_only = true +# 受信した音声データを Ogg ファイルで保存するかどうかです +enable_ogg_file_output = false +# Ogg ファイルの保存先ディレクトリです +ogg_dir = "." # 採用する結果の信頼スコアの最小値です(aws 指定時のみ有効) # minimum_confidence_score が 0.0 の場合は信頼スコアによるフィルタリングは無効です diff --git a/handler.go b/handler.go index 9586524..eb0dc9b 100644 --- a/handler.go +++ b/handler.go @@ -8,6 +8,8 @@ import ( "fmt" "io" "net/http" + "os" + "path" "strings" "time" @@ -41,6 +43,16 @@ func NewSuzuErrorResponse(err error) TranscriptionResult { } } +type soraHeader struct { + SoraChannelID string `header:"Sora-Channel-Id"` + SoraSessionID string `header:"sora-session-id"` + // SoraClientID string `header:"sora-client-id"` + SoraConnectionID string `header:"sora-connection-id"` + // SoraAudioCodecType string `header:"sora-audio-codec-type"` + // SoraAudioSampleRate int64 `header:"sora-audio-sample-rate"` + SoraAudioStreamingLanguageCode string `header:"sora-audio-streaming-language-code"` +} + func getServiceHandler(serviceType string, config Config, channelID, connectionID string, sampleRate uint32, channelCount uint16, languageCode string, onResultFunc any) (serviceHandlerInterface, error) { newHandlerFunc, err := NewServiceHandlerFuncs.get(serviceType) if err != nil { @@ -65,15 +77,7 @@ func (s *Server) createSpeechHandler(serviceType string, onResultFunc func(conte return echo.NewHTTPError(http.StatusBadRequest) } - h := struct { - SoraChannelID string `header:"Sora-Channel-Id"` - // SoraSessionID string `header:"sora-session-id"` - // SoraClientID string `header:"sora-client-id"` - SoraConnectionID string `header:"sora-connection-id"` - // SoraAudioCodecType string `header:"sora-audio-codec-type"` - // SoraAudioSampleRate int64 `header:"sora-audio-sample-rate"` - SoraAudioStreamingLanguageCode string `header:"sora-audio-streaming-language-code"` - }{} + h := soraHeader{} if err := (&echo.DefaultBinder{}).BindHeaders(c, &h); err != nil { zlog.Error(). Err(err). @@ -153,7 +157,7 @@ func (s *Server) createSpeechHandler(serviceType string, onResultFunc func(conte serviceHandlerCtx, cancelServiceHandler := context.WithCancel(ctx) defer cancelServiceHandler() - reader, err := serviceHandler.Handle(serviceHandlerCtx, opusCh) + reader, err := serviceHandler.Handle(serviceHandlerCtx, opusCh, h) if err != nil { zlog.Error(). Err(err). @@ -459,11 +463,26 @@ func readOpus(ctx context.Context, reader io.Reader) chan opusChannel { return opusCh } -func opus2ogg(ctx context.Context, opusCh chan opusChannel, sampleRate uint32, channelCount uint16, c Config) io.ReadCloser { +func opus2ogg(ctx context.Context, opusCh chan opusChannel, sampleRate uint32, channelCount uint16, c Config, header soraHeader) (io.ReadCloser, error) { oggReader, oggWriter := io.Pipe() + writers := []io.Writer{} + writers = append(writers, oggWriter) + + if c.EnableOggFileOutput { + fileName := fmt.Sprintf("%s_%s.ogg", header.SoraSessionID, header.SoraConnectionID) + filePath := path.Join(c.OggDir, fileName) + f, err := os.Create(filePath) + if err != nil { + return nil, err + } + writers = append(writers, f) + } + + multiWriter := io.MultiWriter(writers...) + go func() { - o, err := NewWith(oggWriter, sampleRate, channelCount) + o, err := NewWith(multiWriter, sampleRate, channelCount) if err != nil { oggWriter.CloseWithError(err) return @@ -501,7 +520,7 @@ func opus2ogg(ctx context.Context, opusCh chan opusChannel, sampleRate uint32, c } }() - return oggReader + return oggReader, nil } type opusRequest struct { diff --git a/packet_dump_handler.go b/packet_dump_handler.go index e35e855..565bc20 100644 --- a/packet_dump_handler.go +++ b/packet_dump_handler.go @@ -67,7 +67,7 @@ func (h *PacketDumpHandler) ResetRetryCount() int { return h.RetryCount } -func (h *PacketDumpHandler) Handle(ctx context.Context, opusCh chan opusChannel) (*io.PipeReader, error) { +func (h *PacketDumpHandler) Handle(ctx context.Context, opusCh chan opusChannel, header soraHeader) (*io.PipeReader, error) { c := h.Config filename := c.DumpFile channelID := h.ChannelID diff --git a/service_handler.go b/service_handler.go index 05a3cf2..5b61ec3 100644 --- a/service_handler.go +++ b/service_handler.go @@ -15,7 +15,7 @@ var ( ) type serviceHandlerInterface interface { - Handle(context.Context, chan opusChannel) (*io.PipeReader, error) + Handle(context.Context, chan opusChannel, soraHeader) (*io.PipeReader, error) UpdateRetryCount() int GetRetryCount() int ResetRetryCount() int diff --git a/speech_to_text_handler.go b/speech_to_text_handler.go index 7d0649f..31d8e27 100644 --- a/speech_to_text_handler.go +++ b/speech_to_text_handler.go @@ -91,10 +91,13 @@ func (h *SpeechToTextHandler) ResetRetryCount() int { return h.RetryCount } -func (h *SpeechToTextHandler) Handle(ctx context.Context, opusCh chan opusChannel) (*io.PipeReader, error) { +func (h *SpeechToTextHandler) Handle(ctx context.Context, opusCh chan opusChannel, header soraHeader) (*io.PipeReader, error) { stt := NewSpeechToText(h.Config, h.LanguageCode, int32(h.SampleRate), int32(h.ChannelCount)) - packetReader := opus2ogg(ctx, opusCh, h.SampleRate, h.ChannelCount, h.Config) + packetReader, err := opus2ogg(ctx, opusCh, h.SampleRate, h.ChannelCount, h.Config, header) + if err != nil { + return nil, err + } stream, err := stt.Start(ctx, packetReader) if err != nil { diff --git a/test_handler.go b/test_handler.go index 005ea90..287eb60 100644 --- a/test_handler.go +++ b/test_handler.go @@ -73,7 +73,7 @@ func (h *TestHandler) ResetRetryCount() int { return h.RetryCount } -func (h *TestHandler) Handle(ctx context.Context, opusCh chan opusChannel) (*io.PipeReader, error) { +func (h *TestHandler) Handle(ctx context.Context, opusCh chan opusChannel, header soraHeader) (*io.PipeReader, error) { r, w := io.Pipe() reader := opusChannelToIOReadCloser(ctx, opusCh) From 386af7783cc28747d1c5bea8e39d016bb8db7d8b Mon Sep 17 00:00:00 2001 From: Yoshida Hiroshi Date: Mon, 6 Jan 2025 16:31:38 +0900 Subject: [PATCH 02/11] =?UTF-8?q?writer=20=E3=81=AE=20close=20=E5=87=A6?= =?UTF-8?q?=E7=90=86=E6=99=82=E3=81=AB=20fd=20=E3=82=82=E9=96=89=E3=81=98?= =?UTF-8?q?=E3=82=8B=E3=82=88=E3=81=86=E3=81=AB=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- handler.go | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/handler.go b/handler.go index eb0dc9b..c8920fa 100644 --- a/handler.go +++ b/handler.go @@ -469,10 +469,13 @@ func opus2ogg(ctx context.Context, opusCh chan opusChannel, sampleRate uint32, c writers := []io.Writer{} writers = append(writers, oggWriter) + var f *os.File if c.EnableOggFileOutput { fileName := fmt.Sprintf("%s_%s.ogg", header.SoraSessionID, header.SoraConnectionID) filePath := path.Join(c.OggDir, fileName) - f, err := os.Create(filePath) + + var err error + f, err = os.Create(filePath) if err != nil { return nil, err } @@ -489,6 +492,10 @@ func opus2ogg(ctx context.Context, opusCh chan opusChannel, sampleRate uint32, c } defer o.Close() + if c.EnableOggFileOutput { + o.fd = f + } + for { select { case <-ctx.Done(): From b05972061d29cf6f7ad518930c3477ff98dab5c9 Mon Sep 17 00:00:00 2001 From: Yoshida Hiroshi Date: Mon, 6 Jan 2025 17:03:39 +0900 Subject: [PATCH 03/11] =?UTF-8?q?=E5=81=9C=E6=AD=A2=E6=99=82=E3=81=AB=20eo?= =?UTF-8?q?s=20=E3=82=92=E6=9B=B8=E3=81=8D=E8=BE=BC=E3=82=93=E3=81=A7?= =?UTF-8?q?=E3=81=8B=E3=82=89=E7=B5=82=E3=82=8F=E3=82=89=E3=81=9B=E3=82=8B?= =?UTF-8?q?=E3=81=9F=E3=82=81=E3=81=AB=E3=80=81writer=20=E3=81=AE=E9=A0=86?= =?UTF-8?q?=E7=95=AA=E3=82=92=E5=A4=89=E6=9B=B4=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- handler.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/handler.go b/handler.go index c8920fa..9ba71e2 100644 --- a/handler.go +++ b/handler.go @@ -467,7 +467,6 @@ func opus2ogg(ctx context.Context, opusCh chan opusChannel, sampleRate uint32, c oggReader, oggWriter := io.Pipe() writers := []io.Writer{} - writers = append(writers, oggWriter) var f *os.File if c.EnableOggFileOutput { @@ -481,6 +480,7 @@ func opus2ogg(ctx context.Context, opusCh chan opusChannel, sampleRate uint32, c } writers = append(writers, f) } + writers = append(writers, oggWriter) multiWriter := io.MultiWriter(writers...) From 06f98f4e0433873da2d007ffb0bfb70b06e62ff6 Mon Sep 17 00:00:00 2001 From: Yoshida Hiroshi Date: Tue, 7 Jan 2025 15:39:12 +0900 Subject: [PATCH 04/11] =?UTF-8?q?=E3=83=95=E3=82=A1=E3=82=A4=E3=83=AB?= =?UTF-8?q?=E5=90=8D=E3=82=92=20-=20=E7=B9=8B=E3=81=8E=E3=81=AB=E4=BF=AE?= =?UTF-8?q?=E6=AD=A3=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- handler.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/handler.go b/handler.go index 9ba71e2..07d1b5a 100644 --- a/handler.go +++ b/handler.go @@ -470,7 +470,7 @@ func opus2ogg(ctx context.Context, opusCh chan opusChannel, sampleRate uint32, c var f *os.File if c.EnableOggFileOutput { - fileName := fmt.Sprintf("%s_%s.ogg", header.SoraSessionID, header.SoraConnectionID) + fileName := fmt.Sprintf("%s-%s.ogg", header.SoraSessionID, header.SoraConnectionID) filePath := path.Join(c.OggDir, fileName) var err error From fc0cb5a0a7b8db83ec57352d90e096b7c4f4c8b8 Mon Sep 17 00:00:00 2001 From: Yoshida Hiroshi Date: Tue, 7 Jan 2025 15:50:16 +0900 Subject: [PATCH 05/11] =?UTF-8?q?=E3=83=86=E3=82=B9=E3=83=88=E3=82=92?= =?UTF-8?q?=E8=BF=BD=E5=8A=A0=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- handler_test.go | 150 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 150 insertions(+) diff --git a/handler_test.go b/handler_test.go index ce3d365..17e8429 100644 --- a/handler_test.go +++ b/handler_test.go @@ -1,8 +1,12 @@ package suzu import ( + "context" "errors" + "fmt" "io" + "os" + "path/filepath" "testing" "time" @@ -310,3 +314,149 @@ func TestReadPacketWithHeader(t *testing.T) { }) } } + +func TestOggFileWriting(t *testing.T) { + t.Run("success", func(t *testing.T) { + oggDir, err := os.MkdirTemp("", "ogg-") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(oggDir) + + c := Config{ + EnableOggFileOutput: true, + OggDir: oggDir, + } + + header := soraHeader{ + SoraChannelID: "ogg-test", + SoraSessionID: "C2TFB1QBDS4WD5SX317SWMJ6FM", + SoraConnectionID: "1X0Z8JXZAD5A93X68M2S9NTC4G", + } + + opusCh := make(chan opusChannel) + defer close(opusCh) + + sampleRate := uint32(48000) + channelCount := uint16(1) + + ctx := context.Background() + reader, err := opus2ogg(ctx, opusCh, sampleRate, channelCount, c, header) + if assert.NoError(t, err) { + assert.NotNil(t, reader) + } + defer reader.Close() + + filename := fmt.Sprintf("%s-%s.ogg", header.SoraSessionID, header.SoraConnectionID) + filePath := filepath.Join(oggDir, filename) + _, err = os.Stat(filePath) + assert.NoError(t, err) + }) + + t.Run("disable_ogg_file_output", func(t *testing.T) { + oggDir, err := os.MkdirTemp("", "ogg-") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(oggDir) + + c := Config{ + EnableOggFileOutput: false, + OggDir: oggDir, + } + + header := soraHeader{ + SoraChannelID: "ogg-test", + SoraSessionID: "C2TFB1QBDS4WD5SX317SWMJ6FM", + SoraConnectionID: "1X0Z8JXZAD5A93X68M2S9NTC4G", + } + + opusCh := make(chan opusChannel) + defer close(opusCh) + + sampleRate := uint32(48000) + channelCount := uint16(1) + + ctx := context.Background() + reader, err := opus2ogg(ctx, opusCh, sampleRate, channelCount, c, header) + assert.NoError(t, err) + assert.NotNil(t, reader) + defer reader.Close() + + filename := fmt.Sprintf("%s-%s.ogg", header.SoraSessionID, header.SoraConnectionID) + filePath := filepath.Join(oggDir, filename) + _, err = os.Stat(filePath) + assert.ErrorIs(t, err, os.ErrNotExist) + }) + + t.Run("no permission", func(t *testing.T) { + oggDir, err := os.MkdirTemp("", "ogg-") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(oggDir) + + // 書き込み権限を剥奪 + if err := os.Chmod(oggDir, 0000); err != nil { + t.Fatal(err) + } + defer func() { + if err := os.Chmod(oggDir, 0700); err != nil { + t.Fatal(err) + } + }() + + c := Config{ + EnableOggFileOutput: true, + OggDir: oggDir, + } + + header := soraHeader{ + SoraChannelID: "ogg-test", + SoraSessionID: "C2TFB1QBDS4WD5SX317SWMJ6FM", + SoraConnectionID: "1X0Z8JXZAD5A93X68M2S9NTC4G", + } + + opusCh := make(chan opusChannel) + defer close(opusCh) + + sampleRate := uint32(48000) + channelCount := uint16(1) + + ctx := context.Background() + reader, err := opus2ogg(ctx, opusCh, sampleRate, channelCount, c, header) + assert.ErrorIs(t, err, os.ErrPermission) + assert.Nil(t, reader) + }) + + t.Run("directory does not exist", func(t *testing.T) { + oggDir, err := os.MkdirTemp("", "ogg-") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(oggDir) + + c := Config{ + EnableOggFileOutput: true, + // 既存のディレクトリ名に 0 を付与して存在しないディレクトリを指定する + OggDir: oggDir + "0", + } + + header := soraHeader{ + SoraChannelID: "ogg-test", + SoraSessionID: "C2TFB1QBDS4WD5SX317SWMJ6FM", + SoraConnectionID: "1X0Z8JXZAD5A93X68M2S9NTC4G", + } + + opusCh := make(chan opusChannel) + defer close(opusCh) + + sampleRate := uint32(48000) + channelCount := uint16(1) + + ctx := context.Background() + reader, err := opus2ogg(ctx, opusCh, sampleRate, channelCount, c, header) + assert.ErrorIs(t, err, os.ErrNotExist) + assert.Nil(t, reader) + }) +} From 0c6b29015ff3379c64c6303bd79315b9c04f9505 Mon Sep 17 00:00:00 2001 From: Yoshida Hiroshi Date: Tue, 7 Jan 2025 16:45:55 +0900 Subject: [PATCH 06/11] =?UTF-8?q?=E5=B0=8F=E6=96=87=E5=AD=97=E3=81=AB?= =?UTF-8?q?=E7=9B=B4=E3=81=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- handler.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/handler.go b/handler.go index 07d1b5a..5833a3e 100644 --- a/handler.go +++ b/handler.go @@ -44,7 +44,7 @@ func NewSuzuErrorResponse(err error) TranscriptionResult { } type soraHeader struct { - SoraChannelID string `header:"Sora-Channel-Id"` + SoraChannelID string `header:"sora-channel-id"` SoraSessionID string `header:"sora-session-id"` // SoraClientID string `header:"sora-client-id"` SoraConnectionID string `header:"sora-connection-id"` From bc66b86725ed7882ca9e41fde417806009c1d343 Mon Sep 17 00:00:00 2001 From: Yoshida Hiroshi Date: Wed, 8 Jan 2025 14:30:12 +0900 Subject: [PATCH 07/11] =?UTF-8?q?=E3=83=95=E3=82=A1=E3=82=A4=E3=83=AB?= =?UTF-8?q?=E3=83=98=E3=83=83=E3=83=80=E3=83=BC=E7=A2=BA=E8=AA=8D=E3=81=AE?= =?UTF-8?q?=E7=B0=A1=E5=8D=98=E3=81=AA=E3=83=86=E3=82=B9=E3=83=88=E3=82=92?= =?UTF-8?q?=E8=BF=BD=E5=8A=A0=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- handler_test.go | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/handler_test.go b/handler_test.go index 17e8429..4deb417 100644 --- a/handler_test.go +++ b/handler_test.go @@ -347,10 +347,29 @@ func TestOggFileWriting(t *testing.T) { } defer reader.Close() + // ファイルへの書き込み待ち + time.Sleep(100 * time.Millisecond) + filename := fmt.Sprintf("%s-%s.ogg", header.SoraSessionID, header.SoraConnectionID) filePath := filepath.Join(oggDir, filename) _, err = os.Stat(filePath) assert.NoError(t, err) + + // Ogg ファイルのヘッダーを確認 + f, err := os.Open(filePath) + if err != nil { + t.Fatal(err) + } + defer f.Close() + + buf := make([]byte, 4) + n, err := f.Read(buf) + if err != nil { + if !errors.Is(err, io.EOF) { + t.Fatal(err) + } + } + assert.Equal(t, []byte(`OggS`), buf[:n]) }) t.Run("disable_ogg_file_output", func(t *testing.T) { From 51e45e249268e3bb69c9fc119364650dec4b248d Mon Sep 17 00:00:00 2001 From: Yoshida Hiroshi Date: Wed, 8 Jan 2025 14:33:50 +0900 Subject: [PATCH 08/11] =?UTF-8?q?=E5=A4=89=E6=9B=B4=E5=B1=A5=E6=AD=B4?= =?UTF-8?q?=E3=82=92=E6=9B=B4=E6=96=B0=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGES.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index f916279..7941f8f 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -11,6 +11,13 @@ ## develop +- [ADD] 受信した音声データを Ogg ファイルで保存するかを指定する enable_ogg_file_output を追加する + - デフォルト値: false + - @Hexa +- [ADD] 受信した音声データを Ogg ファイルで保存する場合の保存先ディレクトリを指定する ogg_dir を追加する + - デフォルト値: . + - @Hexa + ### misc - [CHANGE] GitHub Actions の ubuntu-latest を ubuntu-24.04 に変更する From 836b4400826244c1e4f2e4668612c11ebb7faa82 Mon Sep 17 00:00:00 2001 From: Yoshida Hiroshi Date: Wed, 8 Jan 2025 14:36:06 +0900 Subject: [PATCH 09/11] =?UTF-8?q?=E3=82=B3=E3=82=B9=E3=83=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- handler_test.go | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/handler_test.go b/handler_test.go index 4deb417..f9ae64d 100644 --- a/handler_test.go +++ b/handler_test.go @@ -364,11 +364,7 @@ func TestOggFileWriting(t *testing.T) { buf := make([]byte, 4) n, err := f.Read(buf) - if err != nil { - if !errors.Is(err, io.EOF) { - t.Fatal(err) - } - } + assert.NoError(t, err) assert.Equal(t, []byte(`OggS`), buf[:n]) }) From 9a3ce0eec98959bc66ebb44f49ff18adbaede456 Mon Sep 17 00:00:00 2001 From: Yoshida Hiroshi Date: Wed, 8 Jan 2025 15:03:44 +0900 Subject: [PATCH 10/11] =?UTF-8?q?=E5=A4=89=E6=9B=B4=E5=B1=A5=E6=AD=B4?= =?UTF-8?q?=E3=82=92=E6=9B=B4=E6=96=B0=E3=81=99=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGES.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index 7941f8f..350c412 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -12,6 +12,8 @@ ## develop - [ADD] 受信した音声データを Ogg ファイルで保存するかを指定する enable_ogg_file_output を追加する + - 保存するファイル名は、sora-session-id ヘッダーと sora-connection-id ヘッダーの値を使用して作成する + - ${sora-session-id}-${sora-connection-id}.ogg - デフォルト値: false - @Hexa - [ADD] 受信した音声データを Ogg ファイルで保存する場合の保存先ディレクトリを指定する ogg_dir を追加する From dffcb3206d7215484c412abba3f4a08c55194439 Mon Sep 17 00:00:00 2001 From: Yoshida Hiroshi Date: Wed, 8 Jan 2025 15:35:38 +0900 Subject: [PATCH 11/11] =?UTF-8?q?=E3=82=B3=E3=82=B9=E3=83=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 350c412..dd02009 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -12,7 +12,7 @@ ## develop - [ADD] 受信した音声データを Ogg ファイルで保存するかを指定する enable_ogg_file_output を追加する - - 保存するファイル名は、sora-session-id ヘッダーと sora-connection-id ヘッダーの値を使用して作成する + - 保存するファイル名は、sora-session-id ヘッダーと sora-connection-id ヘッダーの値を使用して作成する - ${sora-session-id}-${sora-connection-id}.ogg - デフォルト値: false - @Hexa