feat: openai tts support streaming realtime audio
This commit is contained in:
@@ -273,6 +273,39 @@ func OpenaiHandler(c *gin.Context, info *relaycommon.RelayInfo, resp *http.Respo
|
|||||||
return &simpleResponse.Usage, nil
|
return &simpleResponse.Usage, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func streamTTSResponse(c *gin.Context, resp *http.Response) {
|
||||||
|
c.Writer.WriteHeaderNow()
|
||||||
|
|
||||||
|
flusher, ok := c.Writer.(http.Flusher)
|
||||||
|
if !ok {
|
||||||
|
logger.LogWarn(c, "streaming not supported")
|
||||||
|
_, err := io.Copy(c.Writer, resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
logger.LogWarn(c, err.Error())
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer := make([]byte, 4096)
|
||||||
|
for {
|
||||||
|
n, err := resp.Body.Read(buffer)
|
||||||
|
//logger.LogInfo(c, fmt.Sprintf("streamTTSResponse read %d bytes", n))
|
||||||
|
if n > 0 {
|
||||||
|
if _, writeErr := c.Writer.Write(buffer[:n]); writeErr != nil {
|
||||||
|
logger.LogError(c, writeErr.Error())
|
||||||
|
break
|
||||||
|
}
|
||||||
|
flusher.Flush()
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
if err != io.EOF {
|
||||||
|
logger.LogError(c, err.Error())
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func OpenaiTTSHandler(c *gin.Context, resp *http.Response, info *relaycommon.RelayInfo) *dto.Usage {
|
func OpenaiTTSHandler(c *gin.Context, resp *http.Response, info *relaycommon.RelayInfo) *dto.Usage {
|
||||||
// the status code has been judged before, if there is a body reading failure,
|
// the status code has been judged before, if there is a body reading failure,
|
||||||
// it should be regarded as a non-recoverable error, so it should not return err for external retry.
|
// it should be regarded as a non-recoverable error, so it should not return err for external retry.
|
||||||
@@ -288,11 +321,17 @@ func OpenaiTTSHandler(c *gin.Context, resp *http.Response, info *relaycommon.Rel
|
|||||||
c.Writer.Header().Set(k, v[0])
|
c.Writer.Header().Set(k, v[0])
|
||||||
}
|
}
|
||||||
c.Writer.WriteHeader(resp.StatusCode)
|
c.Writer.WriteHeader(resp.StatusCode)
|
||||||
|
|
||||||
|
isStreaming := resp.ContentLength == -1 || resp.Header.Get("Content-Length") == ""
|
||||||
|
if isStreaming {
|
||||||
|
streamTTSResponse(c, resp)
|
||||||
|
} else {
|
||||||
c.Writer.WriteHeaderNow()
|
c.Writer.WriteHeaderNow()
|
||||||
_, err := io.Copy(c.Writer, resp.Body)
|
_, err := io.Copy(c.Writer, resp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.LogError(c, err.Error())
|
logger.LogError(c, err.Error())
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return usage
|
return usage
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user