Beispiel #1
0
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)
}
Beispiel #2
0
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
}