我正在尝试通过io.ReadFull以块的形式处理数据以节省内存来下载和解密 HLS 流:为简单起见,省略了不相关的代码部分。func main() { f, _ := os.Create(out.ts) for _, v := range mediaPlaylist { resp, _ := http.Get(v.URI) for { r, err := decryptHLS(key, iv, resp.Body) if err != nil && err == io.EOF { break else if err != nil && err != io.ErrUnexpectedEOF { panic(err) } io.Copy(f, r) } }}func decryptHLS(key []byte, iv []byte, r io.Reader) (io.Reader, error) { block, _ := aes.NewCipher(key) buf := make([]byte, 8192) mode := cipher.NewCBCDecrypter(block, iv) n, err := io.ReadFull(r, buf) if err != nil && err != io.ErrUnexpectedEOF { return nil, err } mode.CryptBlocks(buf, buf) return bytes.NewReader(buf[:n]), err}起初,这似乎可以正常工作,因为文件大小正确且下载过程中没有错误,但视频已损坏。不完全因为该文件仍被识别为视频,但图像和声音失真。如果我更改要使用的代码ioutil.ReadAll,最终的视频文件将不再损坏:func main() { f, _ := os.Create(out.ts) for _, v := range mediaPlaylist { resp, _ := http.Get(v.URI) segment, _ := ioutil.ReadAll(resp.Body) r, _ := decryptHLS(key, iv, &segment) io.Copy(f, r) }}func decryptHLS(key []byte, iv []byte, s *[]byte) io.Reader { block, _ := aes.NewCipher(key) mode := cipher.NewCBCDecrypter(block, iv) mode.CryptBlocks(*s, *s) return bytes.NewReader(*s)}任何想法为什么它在将整个段读入内存时正常工作,而不是io.ReadFull在块中使用和处理它时?
1 回答
忽然笑
TA贡献1806条经验 获得超5个赞
在内部, CBCDecrypter 会复制您的iv
,因此后续块以初始 IV 开头,而不是由先前解密改变的那个。
创建一次解密器,您应该能够继续重复使用它来逐块解密(假设块大小是此加密算法预期的块大小的倍数)。
- 1 回答
- 0 关注
- 82 浏览
添加回答
举报
0/150
提交
取消