func (editor *OggTagEditor) WriteTag(src, dst string, tag Tag) error { err := editor.readFile(src) if err != nil { return err } idPage, commentPages, restData := editor.splitFileData(editor.file) newCommentPages, newSetupPages, numberOfPages := editor.makeNewPages(commentPages, tag) newPrefix := make([]byte, len(idPage)+len(newCommentPages)+len(newSetupPages)) copy(newPrefix, idPage) copy(newPrefix[len(idPage):], newCommentPages) copy(newPrefix[len(idPage)+len(newCommentPages):], newSetupPages) // fix page numbers and CRCs sequence := numberOfPages + 1 data := restData for len(data) > oggPageHeaderSize { pageSize := editor.getPageSize(data) utils.WriteInt32Le(sequence, data[18:22]) // number utils.WriteUint32Le(0, data[22:26]) // zero CRC utils.WriteUint32Le(editor.crc(data[:pageSize]), data[22:26]) // CRC sequence++ data = data[pageSize:] } return ioutil.WriteFile(dst, append(newPrefix, restData...), 0666) }
func (editor *OggTagEditor) packTagDataIntoFrames(bitstream, sequence int, tagData []byte) ([]byte, int) { totalTagSize := len(tagData) if totalTagSize == 0 { return nil, 0 } tagSize := 0 size := 0 pages := 0 result := make([]byte, totalTagSize+282*(totalTagSize/maxFrameDataSize+1)) for tagSize < totalTagSize { headerSize, dataSize := editor.fillHeader(result[size:], bitstream, sequence+pages, totalTagSize-tagSize) pages++ if tagSize != 0 { result[size+len(oggPageMagic)+1] = headerTypeContinue } size += headerSize copy(result[size:size+dataSize], tagData[:dataSize]) size += dataSize tagSize += dataSize tagData = tagData[dataSize:] checksum := editor.crc(result[size-headerSize-dataSize : size]) utils.WriteUint32Le(checksum, result[size-headerSize-dataSize+22:size-headerSize-dataSize+26]) } return result[:size], pages }