Open abhobe opened 3 years ago
I think something is accidentally lost in the process of converting []byte to io.ReadCloser, or os.File is the most appropriate for mp3.Decode, so I recommend converting []byte to os.File; And I succeeded, solved the problem, and got the music length.
I try to use os.NewFile(0, "").Write()
but the console output is garbled, and the sound cannot be played.
So I wrote this myself:
// Package byteToFile
// []byte to fs.file, reference embed
package byteToFile
import (
"io"
"io/fs"
"reflect"
"time"
)
// A file is a single file in the FS.
// It implements fs.FileInfo and fs.DirEntry.
type file struct {
name string
data string
hash [16]byte // truncated SHA256 hash
}
func (f *file) Name() string { return f.name }
func (f *file) Size() int64 { return int64(len(f.data)) }
func (f *file) ModTime() time.Time { return time.Time{} }
func (f *file) IsDir() bool { return false }
func (f *file) Sys() any { return nil }
func (f *file) Type() fs.FileMode { return f.Mode().Type() }
func (f *file) Info() (fs.FileInfo, error) { return f, nil }
func (f *file) Mode() fs.FileMode {
if f.IsDir() {
return fs.ModeDir | 0555
}
return 0444
}
// An openFile is a regular file open for reading.
type openFile struct {
f *file // the file itself
offset int64 // current read offset
}
func (f *openFile) Close() error { return nil }
func (f *openFile) Stat() (fs.FileInfo, error) { return f.f, nil }
// Read reads up to len(b) bytes from the File and stores them in b.
// It returns the number of bytes read and any error encountered.
// At end of file, Read returns 0, io.EOF.
func (f *openFile) Read(b []byte) (int, error) {
if f.offset >= int64(len(f.f.data)) {
return 0, io.EOF
}
if f.offset < 0 {
return 0, &fs.PathError{Op: "read", Path: f.f.name, Err: fs.ErrInvalid}
}
n := copy(b, f.f.data[f.offset:])
f.offset += int64(n)
return n, nil
}
var (
_ io.Seeker = (*openFile)(nil)
_ fs.FileInfo = (*file)(nil)
)
func (f *openFile) Seek(offset int64, whence int) (int64, error) {
switch whence {
case 0:
// offset += 0
case 1:
offset += f.offset
case 2:
offset += int64(len(f.f.data))
}
if offset < 0 || offset > int64(len(f.f.data)) {
return 0, &fs.PathError{Op: "seek", Path: f.f.name, Err: fs.ErrInvalid}
}
f.offset = offset
return offset, nil
}
func (f *openFile) Write(b []byte) (int, error) {
if reflect.ValueOf(f).IsNil() {
return 0, &fs.PathError{Op: "write", Path: f.f.name, Err: fs.ErrInvalid}
}
f.f.data += string(b)
return len(b), nil
}
func New() *openFile {
return &openFile{
f: &file{},
offset: 0,
}
}
It works like this:
package main
import (
"fmt"
"demo/byteToFile"
)
func main(){
data := []byte("I like 邓文怡")
object := byteToFile.New()
_,err := object.Write(data)
if err != nil{
panic(err)
}
read := make([]byte,len(data))
_,err = object.Read(read)
if err != nil{
panic(err)
}
fmt.Println(string(read))
}
Hope it can help you! I like beep it's good!
In order for Len and Seek methods to work you need to implement io.Seeker on the struct you pass into mp3.Decode, which NopCloser does not
Tested it, and implementing io.Seeker wont actually help, because beep uses go-mp3 package, and it sets the length when you call mp3.Decode, which means it will only be the size of the buffer at that time.
我认为在将[]字节转换为io.ReadCloser或os.File最适合mp3的过程中,意外丢失了一些东西。解码,所以我建议将[]字节转换为os.File;我成功了,解决了问题,并得到了音乐长度。我尝试使用
os.NewFile(0, "").Write()
,但控制台输出混乱,无法播放声音。所以我自己写了这个:// Package byteToFile // []byte to fs.file, reference embed package byteToFile import ( "io" "io/fs" "reflect" "time" ) // A file is a single file in the FS. // It implements fs.FileInfo and fs.DirEntry. type file struct { name string data string hash [16]byte // truncated SHA256 hash } func (f *file) Name() string { return f.name } func (f *file) Size() int64 { return int64(len(f.data)) } func (f *file) ModTime() time.Time { return time.Time{} } func (f *file) IsDir() bool { return false } func (f *file) Sys() any { return nil } func (f *file) Type() fs.FileMode { return f.Mode().Type() } func (f *file) Info() (fs.FileInfo, error) { return f, nil } func (f *file) Mode() fs.FileMode { if f.IsDir() { return fs.ModeDir | 0555 } return 0444 } // An openFile is a regular file open for reading. type openFile struct { f *file // the file itself offset int64 // current read offset } func (f *openFile) Close() error { return nil } func (f *openFile) Stat() (fs.FileInfo, error) { return f.f, nil } // Read reads up to len(b) bytes from the File and stores them in b. // It returns the number of bytes read and any error encountered. // At end of file, Read returns 0, io.EOF. func (f *openFile) Read(b []byte) (int, error) { if f.offset >= int64(len(f.f.data)) { return 0, io.EOF } if f.offset < 0 { return 0, &fs.PathError{Op: "read", Path: f.f.name, Err: fs.ErrInvalid} } n := copy(b, f.f.data[f.offset:]) f.offset += int64(n) return n, nil } var ( _ io.Seeker = (*openFile)(nil) _ fs.FileInfo = (*file)(nil) ) func (f *openFile) Seek(offset int64, whence int) (int64, error) { switch whence { case 0: // offset += 0 case 1: offset += f.offset case 2: offset += int64(len(f.f.data)) } if offset < 0 || offset > int64(len(f.f.data)) { return 0, &fs.PathError{Op: "seek", Path: f.f.name, Err: fs.ErrInvalid} } f.offset = offset return offset, nil } func (f *openFile) Write(b []byte) (int, error) { if reflect.ValueOf(f).IsNil() { return 0, &fs.PathError{Op: "write", Path: f.f.name, Err: fs.ErrInvalid} } f.f.data += string(b) return len(b), nil } func New() *openFile { return &openFile{ f: &file{}, offset: 0, } }
它的工作原理是这样的:
package main import ( "fmt" "demo/byteToFile" ) func main(){ data := []byte("I like 邓文怡") object := byteToFile.New() _,err := object.Write(data) if err != nil{ panic(err) } read := make([]byte,len(data)) _,err = object.Read(read) if err != nil{ panic(err) } fmt.Println(string(read)) }
希望它能帮到你!我喜欢哔哔声,很好!
I think something is accidentally lost in the process of converting []byte to io.ReadCloser, or os.File is the most appropriate for mp3.Decode, so I recommend converting []byte to os.File; And I succeeded, solved the problem, and got the music length. I try to use
os.NewFile(0, "").Write()
but the console output is garbled, and the sound cannot be played. So I wrote this myself:// Package byteToFile // []byte to fs.file, reference embed package byteToFile import ( "io" "io/fs" "reflect" "time" ) // A file is a single file in the FS. // It implements fs.FileInfo and fs.DirEntry. type file struct { name string data string hash [16]byte // truncated SHA256 hash } func (f *file) Name() string { return f.name } func (f *file) Size() int64 { return int64(len(f.data)) } func (f *file) ModTime() time.Time { return time.Time{} } func (f *file) IsDir() bool { return false } func (f *file) Sys() any { return nil } func (f *file) Type() fs.FileMode { return f.Mode().Type() } func (f *file) Info() (fs.FileInfo, error) { return f, nil } func (f *file) Mode() fs.FileMode { if f.IsDir() { return fs.ModeDir | 0555 } return 0444 } // An openFile is a regular file open for reading. type openFile struct { f *file // the file itself offset int64 // current read offset } func (f *openFile) Close() error { return nil } func (f *openFile) Stat() (fs.FileInfo, error) { return f.f, nil } // Read reads up to len(b) bytes from the File and stores them in b. // It returns the number of bytes read and any error encountered. // At end of file, Read returns 0, io.EOF. func (f *openFile) Read(b []byte) (int, error) { if f.offset >= int64(len(f.f.data)) { return 0, io.EOF } if f.offset < 0 { return 0, &fs.PathError{Op: "read", Path: f.f.name, Err: fs.ErrInvalid} } n := copy(b, f.f.data[f.offset:]) f.offset += int64(n) return n, nil } var ( _ io.Seeker = (*openFile)(nil) _ fs.FileInfo = (*file)(nil) ) func (f *openFile) Seek(offset int64, whence int) (int64, error) { switch whence { case 0: // offset += 0 case 1: offset += f.offset case 2: offset += int64(len(f.f.data)) } if offset < 0 || offset > int64(len(f.f.data)) { return 0, &fs.PathError{Op: "seek", Path: f.f.name, Err: fs.ErrInvalid} } f.offset = offset return offset, nil } func (f *openFile) Write(b []byte) (int, error) { if reflect.ValueOf(f).IsNil() { return 0, &fs.PathError{Op: "write", Path: f.f.name, Err: fs.ErrInvalid} } f.f.data += string(b) return len(b), nil } func New() *openFile { return &openFile{ f: &file{}, offset: 0, } }
It works like this:
package main import ( "fmt" "demo/byteToFile" ) func main(){ data := []byte("I like 邓文怡") object := byteToFile.New() _,err := object.Write(data) if err != nil{ panic(err) } read := make([]byte,len(data)) _,err = object.Read(read) if err != nil{ panic(err) } fmt.Println(string(read)) }
Hope it can help you! I like beep it's good!
I think the problem has been solved. This is my blog article, which contains more information: https://blog.csdn.net/Deng_Xian_Sheng/article/details/125128054?ops_request_misc=&request_id=e233f01259634c8a88aba26c32e9cd7c&biz_id=&utm_medium=distribute.pc_search_result.none -Task blog-2~blog~koosearch~default-1-125128054 null null. 268 ^ v1 ^ control&utm_ Term=beep&spm=1018.2226.3001.4450
I'm trying to read an audio file through a reader from a
[]byte
array, but when I do this, the length of the output stream is0
. However, using the traditional method ofos.Open()
, the length is9589248
. Both methods can play the audio, but I can't use.Seek()
when using thebyte
array. I'm not sure what's wrong, any help would be appreciated.