def get_metadata(self): """returns a MetaData object, or None raises IOError if unable to read the file""" from cStringIO import StringIO from audiotools.bitstream import BitstreamReader from audiotools.ogg import PacketReader, PageReader from audiotools.vorbiscomment import VorbisComment reader = PacketReader(PageReader(open(self.filename, "rb"))) identification = reader.read_packet() comment = BitstreamReader(StringIO(reader.read_packet()), True) (packet_type, packet_header) = comment.parse("8u 6b") if ((packet_type == 3) and (packet_header == 'vorbis')): vendor_string = \ comment.read_bytes(comment.read(32)).decode('utf-8') comment_strings = [ comment.read_bytes(comment.read(32)).decode('utf-8') for i in xrange(comment.read(32))] if (comment.read(1) == 1): # framing bit return VorbisComment(comment_strings, vendor_string) else: return None else: return None
def get_metadata(self): """returns a MetaData object, or None raises IOError if unable to read the file""" from io import BytesIO from audiotools.bitstream import BitstreamReader from audiotools.ogg import PacketReader, PageReader reader = PacketReader(PageReader(open(self.filename, "rb"))) identification = reader.read_packet() comment = BitstreamReader(BytesIO(reader.read_packet()), True) if (comment.read_bytes(8) == "OpusTags"): vendor_string = \ comment.read_bytes(comment.read(32)).decode('utf-8') comment_strings = [ comment.read_bytes(comment.read(32)).decode('utf-8') for i in range(comment.read(32)) ] return VorbisComment(comment_strings, vendor_string) else: return None
def get_metadata(self): """returns a MetaData object, or None raises IOError if unable to read the file""" from audiotools.ogg import PacketReader,PageReader from cStringIO import StringIO from audiotools.bitstream import BitstreamReader packets = PacketReader(PageReader(open(self.filename, "rb"))) identification = packets.read_packet() comment = BitstreamReader(StringIO(packets.read_packet()), True) if (comment.read_bytes(8) == "OpusTags"): vendor_string = \ comment.read_bytes(comment.read(32)).decode('utf-8') comment_strings = [ comment.read_bytes(comment.read(32)).decode('utf-8') for i in xrange(comment.read(32))] return VorbisComment(comment_strings, vendor_string) else: return None
def update_metadata(self, metadata): """takes this track's current MetaData object as returned by get_metadata() and sets this track's metadata with any fields updated in that object raises IOError if unable to write the file """ import os from audiotools import TemporaryFile from audiotools.ogg import (PageReader, PacketReader, PageWriter, packet_to_pages, packets_to_pages) from audiotools.vorbiscomment import VorbisComment from audiotools.bitstream import BitstreamRecorder if (metadata is None): return elif (not isinstance(metadata, VorbisComment)): from .text import ERR_FOREIGN_METADATA raise ValueError(ERR_FOREIGN_METADATA) elif (not os.access(self.filename, os.W_OK)): raise IOError(self.filename) original_ogg = PacketReader(PageReader(file(self.filename, "rb"))) new_ogg = PageWriter(TemporaryFile(self.filename)) sequence_number = 0 #transfer current file's identification packet in its own page identification_packet = original_ogg.read_packet() for (i, page) in enumerate(packet_to_pages( identification_packet, self.__serial_number__, starting_sequence_number=sequence_number)): page.stream_beginning = (i == 0) new_ogg.write(page) sequence_number += 1 #discard the current file's comment packet comment_packet = original_ogg.read_packet() #generate new comment packet comment_writer = BitstreamRecorder(True) comment_writer.build("8u 6b", (3, "vorbis")) vendor_string = metadata.vendor_string.encode('utf-8') comment_writer.build("32u %db" % (len(vendor_string)), (len(vendor_string), vendor_string)) comment_writer.write(32, len(metadata.comment_strings)) for comment_string in metadata.comment_strings: comment_string = comment_string.encode('utf-8') comment_writer.build("32u %db" % (len(comment_string)), (len(comment_string), comment_string)) comment_writer.build("1u a", (1,)) # framing bit #transfer codebooks packet from original file to new file codebooks_packet = original_ogg.read_packet() for page in packets_to_pages( [comment_writer.data(), codebooks_packet], self.__serial_number__, starting_sequence_number=sequence_number): new_ogg.write(page) sequence_number += 1 #transfer remaining pages after re-sequencing page = original_ogg.read_page() page.sequence_number = sequence_number sequence_number += 1 new_ogg.write(page) while (not page.stream_end): page = original_ogg.read_page() page.sequence_number = sequence_number page.bitstream_serial_number = self.__serial_number__ sequence_number += 1 new_ogg.write(page) original_ogg.close() new_ogg.close()
def update_metadata(self, metadata): """takes this track's current MetaData object as returned by get_metadata() and sets this track's metadata with any fields updated in that object raises IOError if unable to write the file """ import os from audiotools import TemporaryFile from audiotools.ogg import (PageReader, PacketReader, PageWriter, packet_to_pages) from audiotools.bitstream import BitstreamRecorder if (metadata is None): return elif (not isinstance(metadata, VorbisComment)): from .text import ERR_FOREIGN_METADATA raise ValueError(ERR_FOREIGN_METADATA) elif (not os.access(self.filename, os.W_OK)): raise IOError(self.filename) original_ogg = PacketReader(PageReader(file(self.filename, "rb"))) new_ogg = PageWriter(TemporaryFile(self.filename)) #transfer current file's identification page/packet #(the ID packet is always fixed size, and fits in one page) identification_page = original_ogg.read_page() new_ogg.write(identification_page) sequence_number = 1 #discard the current file's comment packet original_ogg.read_packet() #write the new comment packet in its own page(s) comment_writer = BitstreamRecorder(True) comment_writer.write_bytes("OpusTags") vendor_string = metadata.vendor_string.encode('utf-8') comment_writer.build("32u %db" % (len(vendor_string)), (len(vendor_string), vendor_string)) comment_writer.write(32, len(metadata.comment_strings)) for comment_string in metadata.comment_strings: comment_string = comment_string.encode('utf-8') comment_writer.build("32u %db" % (len(comment_string)), (len(comment_string), comment_string)) for page in packet_to_pages( comment_writer.data(), identification_page.bitstream_serial_number, starting_sequence_number=sequence_number): new_ogg.write(page) sequence_number += 1 #transfer remaining pages after re-sequencing page = original_ogg.read_page() page.sequence_number = sequence_number sequence_number += 1 new_ogg.write(page) while (not page.stream_end): page = original_ogg.read_page() page.sequence_number = sequence_number sequence_number += 1 new_ogg.write(page) original_ogg.close() new_ogg.close()