Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
phsl
/
new-api
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
da0d3ea9
authored
Dec 13, 2025
by
CaIon
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix(audio): improve WAV duration calculation with enhanced PCM size handling
parent
06d1bd40
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
55 additions
and
4 deletions
+55
-4
common/audio.go
+55
-4
No files found.
common/audio.go
View file @
da0d3ea9
...
@@ -71,15 +71,66 @@ func getMP3Duration(r io.Reader) (float64, error) {
...
@@ -71,15 +71,66 @@ func getMP3Duration(r io.Reader) (float64, error) {
// getWAVDuration 解析 WAV 文件头以获取时长。
// getWAVDuration 解析 WAV 文件头以获取时长。
func
getWAVDuration
(
r
io
.
ReadSeeker
)
(
float64
,
error
)
{
func
getWAVDuration
(
r
io
.
ReadSeeker
)
(
float64
,
error
)
{
// 1. 强制复位指针
r
.
Seek
(
0
,
io
.
SeekStart
)
dec
:=
wav
.
NewDecoder
(
r
)
dec
:=
wav
.
NewDecoder
(
r
)
// IsValidFile 会读取 fmt 块
if
!
dec
.
IsValidFile
()
{
if
!
dec
.
IsValidFile
()
{
return
0
,
errors
.
New
(
"invalid wav file"
)
return
0
,
errors
.
New
(
"invalid wav file"
)
}
}
d
,
err
:=
dec
.
Duration
()
if
err
!=
nil
{
// 尝试寻找 data 块
return
0
,
errors
.
Wrap
(
err
,
"failed to get wav duration"
)
if
err
:=
dec
.
FwdToPCM
();
err
!=
nil
{
return
0
,
errors
.
Wrap
(
err
,
"failed to find PCM data chunk"
)
}
}
return
d
.
Seconds
(),
nil
pcmSize
:=
int64
(
dec
.
PCMSize
)
// 如果读出来的 Size 是 0,尝试用文件大小反推
if
pcmSize
==
0
{
// 获取文件总大小
currentPos
,
_
:=
r
.
Seek
(
0
,
io
.
SeekCurrent
)
// 当前通常在 data chunk header 之后
endPos
,
_
:=
r
.
Seek
(
0
,
io
.
SeekEnd
)
fileSize
:=
endPos
// 恢复位置(虽然如果不继续读也没关系)
r
.
Seek
(
currentPos
,
io
.
SeekStart
)
// 数据区大小 ≈ 文件总大小 - 当前指针位置(即Header大小)
// 注意:FwdToPCM 成功后,CurrentPos 应该刚好指向 Data 区数据的开始
// 或者是 Data Chunk ID + Size 之后。
// WAV Header 一般 44 字节。
if
fileSize
>
44
{
// 如果 FwdToPCM 成功,Reader 应该位于 data 块的数据起始处
// 所以剩余的所有字节理论上都是音频数据
pcmSize
=
fileSize
-
currentPos
// 简单的兜底:如果算出来还是负数或0,强制按文件大小-44计算
if
pcmSize
<=
0
{
pcmSize
=
fileSize
-
44
}
}
}
numChans
:=
int64
(
dec
.
NumChans
)
bitDepth
:=
int64
(
dec
.
BitDepth
)
sampleRate
:=
float64
(
dec
.
SampleRate
)
if
sampleRate
==
0
||
numChans
==
0
||
bitDepth
==
0
{
return
0
,
errors
.
New
(
"invalid wav header metadata"
)
}
bytesPerFrame
:=
numChans
*
(
bitDepth
/
8
)
if
bytesPerFrame
==
0
{
return
0
,
errors
.
New
(
"invalid byte depth calculation"
)
}
totalFrames
:=
pcmSize
/
bytesPerFrame
durationSeconds
:=
float64
(
totalFrames
)
/
sampleRate
return
durationSeconds
,
nil
}
}
// getFLACDuration 解析 FLAC 文件的 STREAMINFO 块。
// getFLACDuration 解析 FLAC 文件的 STREAMINFO 块。
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment