From a7654c206caf3bbaddf5f6ce900df892e3178dda Mon Sep 17 00:00:00 2001 From: MarkYoo23 <71996956+MarkYoo23@users.noreply.github.com> Date: Sat, 26 Oct 2024 13:19:24 +0900 Subject: [PATCH 1/4] =?UTF-8?q?feat=20:=20mp3=20=ED=8C=8C=EC=9D=BC?= =?UTF-8?q?=EC=9D=98=20=EB=B0=B0=EC=86=8D=20=EA=B8=B0=EB=8A=A5=EC=9D=84=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84=20(red)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mark/tests/test_mp3.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/mark/tests/test_mp3.py b/mark/tests/test_mp3.py index 9457d67..1260e71 100644 --- a/mark/tests/test_mp3.py +++ b/mark/tests/test_mp3.py @@ -50,5 +50,16 @@ def test_mp3_cut(self): output.save("../resource/output.mp3") + def test_mp3_set_speed(self): + mp3 = MP3(self.reader) + mp3.set_header() + mp3.set_frame_size() + mp3.set_frame_count() + mp3.set_play_time() + + output = mp3.set_speed(2) + output.save("../resource/output_x2.mp3") + + if __name__ == '__main__': unittest.main() From 0a127d9fdff9e0c60a2f9ae297ce1581211823c7 Mon Sep 17 00:00:00 2001 From: MarkYoo23 <71996956+MarkYoo23@users.noreply.github.com> Date: Sat, 26 Oct 2024 14:40:08 +0900 Subject: [PATCH 2/4] =?UTF-8?q?feat=20:=20mp3=20=ED=8C=8C=EC=9D=BC?= =?UTF-8?q?=EC=9D=98=20=EB=B0=B0=EC=86=8D=20=EA=B8=B0=EB=8A=A5=EC=9D=84=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84=20(green)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mark/src/mp3.py | 44 +++++++++++++++++++++++++++++++++++++++++ mark/src/mp3_file_io.py | 9 +++++++++ mark/tests/test_mp3.py | 15 +++++++++++--- 3 files changed, 65 insertions(+), 3 deletions(-) diff --git a/mark/src/mp3.py b/mark/src/mp3.py index 42de87b..8d99059 100644 --- a/mark/src/mp3.py +++ b/mark/src/mp3.py @@ -36,6 +36,13 @@ def set_play_time(self): def get_play_time(self): return self.play_time + def get_frame(self, index) -> bytes: + offset = 4 + start = offset + index * self.frame_size + end = start + self.frame_size + frame = self.file_io.get_bytes(start, end) + return frame + def cut(self, start_time, end_time): start_frame = int(start_time * self.header.sampling_rate / 1152) end_frame = int(end_time * self.header.sampling_rate / 1152) @@ -47,5 +54,42 @@ def cut(self, start_time, end_time): io = self.file_io.cut_frames(start_byte, end_byte) return MP3(io) + def change_speed_down(self, speed: int): + if speed <= 0: + raise ValueError("Speed must be greater than 0") + + # 일단 전체 프레임을 배열로 저장한다 + frames = [] + for i in range(self.frame_count): + frames.append(self.get_frame(i)) + + new_frames = bytearray() + for i in range(self.frame_count): + for _ in range(speed): + new_frames.extend(frames[i]) + + io = self.file_io.change_frames(new_frames) + return MP3(io) + + def change_speed_up(self, speed: int): + if speed <= 0: + raise ValueError("Speed must be greater than 0") + + # 일단 전체 프레임을 배열로 저장한다 + frames = [] + for i in range(self.frame_count): + frames.append(self.get_frame(i)) + + new_frames = bytearray() + + i = 0 + while i < self.frame_count: + new_frames.extend(frames[i]) + i += speed + + io = self.file_io.change_frames(new_frames) + return MP3(io) + def save(self, file_path): self.file_io.save(file_path) + diff --git a/mark/src/mp3_file_io.py b/mark/src/mp3_file_io.py index 22011a2..7ec99c3 100644 --- a/mark/src/mp3_file_io.py +++ b/mark/src/mp3_file_io.py @@ -27,6 +27,9 @@ def read_all(self): def get(self, size): return self.bytes[0:size] + def get_bytes(self, start, end): + return self.bytes[start:end] + def get_all(self): return self.bytes @@ -62,6 +65,12 @@ def cut_frames(self, start_byte, end_byte): io.bytes = self.bytes[0:4] + self.bytes[start_byte:end_byte] return io + def change_frames(self, frames : bytearray): + new_bytes = self.bytes[0:4] + frames + io = MP3FileIo() + io.bytes = new_bytes + return io + def save(self, file_path): try: file_obj = open(file_path, 'wb') diff --git a/mark/tests/test_mp3.py b/mark/tests/test_mp3.py index 1260e71..d5ecb7e 100644 --- a/mark/tests/test_mp3.py +++ b/mark/tests/test_mp3.py @@ -50,16 +50,25 @@ def test_mp3_cut(self): output.save("../resource/output.mp3") - def test_mp3_set_speed(self): + def test_mp3_set_down_speed(self): mp3 = MP3(self.reader) mp3.set_header() mp3.set_frame_size() mp3.set_frame_count() mp3.set_play_time() - output = mp3.set_speed(2) - output.save("../resource/output_x2.mp3") + output = mp3.change_speed_down(2) + output.save("../resource/output_down_x2.mp3") + def test_mp3_set_up_speed(self): + mp3 = MP3(self.reader) + mp3.set_header() + mp3.set_frame_size() + mp3.set_frame_count() + mp3.set_play_time() + + output = mp3.change_speed_up(2) + output.save("../resource/output_up_x2.mp3") if __name__ == '__main__': unittest.main() From 4989a836637a1c54bb435d56756f74742e0bd733 Mon Sep 17 00:00:00 2001 From: MarkYoo23 <71996956+MarkYoo23@users.noreply.github.com> Date: Sat, 26 Oct 2024 15:22:27 +0900 Subject: [PATCH 3/4] =?UTF-8?q?refactor=20:=20mp3=20=ED=8C=8C=EC=9D=BC?= =?UTF-8?q?=EC=9D=98=20=EB=B0=B0=EC=86=8D=20=EA=B8=B0=EB=8A=A5=EC=9D=84=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mark/src/mp3.py | 17 +++++++++-------- mark/src/mp3_file_io.py | 7 +++++-- mark/tests/test_mp3.py | 2 +- 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/mark/src/mp3.py b/mark/src/mp3.py index 8d99059..6b505f2 100644 --- a/mark/src/mp3.py +++ b/mark/src/mp3.py @@ -37,9 +37,9 @@ def get_play_time(self): return self.play_time def get_frame(self, index) -> bytes: - offset = 4 - start = offset + index * self.frame_size - end = start + self.frame_size + frame_size = self.header.calc_frame_size() + start = 4 + index * frame_size + end = start + frame_size frame = self.file_io.get_bytes(start, end) return frame @@ -48,7 +48,7 @@ def cut(self, start_time, end_time): end_frame = int(end_time * self.header.sampling_rate / 1152) frame_size = self.header.calc_frame_size() - start_byte = start_frame * frame_size + start_byte = 4 + start_frame * frame_size end_byte = end_frame * frame_size io = self.file_io.cut_frames(start_byte, end_byte) @@ -63,10 +63,10 @@ def change_speed_down(self, speed: int): for i in range(self.frame_count): frames.append(self.get_frame(i)) - new_frames = bytearray() + new_frames = [] for i in range(self.frame_count): for _ in range(speed): - new_frames.extend(frames[i]) + new_frames.append(frames[i]) io = self.file_io.change_frames(new_frames) return MP3(io) @@ -80,11 +80,12 @@ def change_speed_up(self, speed: int): for i in range(self.frame_count): frames.append(self.get_frame(i)) - new_frames = bytearray() + new_frames = [] i = 0 while i < self.frame_count: - new_frames.extend(frames[i]) + print(f"Processing frame {i}") + new_frames.append(frames[i]) i += speed io = self.file_io.change_frames(new_frames) diff --git a/mark/src/mp3_file_io.py b/mark/src/mp3_file_io.py index 7ec99c3..72b5509 100644 --- a/mark/src/mp3_file_io.py +++ b/mark/src/mp3_file_io.py @@ -65,8 +65,11 @@ def cut_frames(self, start_byte, end_byte): io.bytes = self.bytes[0:4] + self.bytes[start_byte:end_byte] return io - def change_frames(self, frames : bytearray): - new_bytes = self.bytes[0:4] + frames + def change_frames(self, frames): + new_bytes = self.bytes[0:4] + + for frame in frames: + new_bytes += frame io = MP3FileIo() io.bytes = new_bytes return io diff --git a/mark/tests/test_mp3.py b/mark/tests/test_mp3.py index d5ecb7e..a70b68c 100644 --- a/mark/tests/test_mp3.py +++ b/mark/tests/test_mp3.py @@ -46,7 +46,7 @@ def test_mp3_cut(self): mp3.set_frame_count() mp3.set_play_time() - output = mp3.cut(0, 10) + output = mp3.cut(0, 20) output.save("../resource/output.mp3") From 25cedf6fd4442c8a0aea07e79eb82ba897a81463 Mon Sep 17 00:00:00 2001 From: MarkYoo23 <71996956+MarkYoo23@users.noreply.github.com> Date: Sat, 26 Oct 2024 19:21:12 +0900 Subject: [PATCH 4/4] =?UTF-8?q?refactor=20:=20mp3=20=EC=9D=BD=EA=B8=B0=20?= =?UTF-8?q?=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95=20=EB=B0=8F=20=EB=A6=AC?= =?UTF-8?q?=ED=8C=A9=ED=84=B0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../inspectionProfiles/Project_Default.xml | 7 ++ mark/src/app.py | 26 +++-- mark/src/main.py | 4 +- mark/src/mp3.py | 104 ++++-------------- mark/src/mp3Factory.py | 56 ++++++++++ mark/src/mp3_file_io.py | 61 ++-------- mark/src/mp3_file_io_factory.py | 15 +++ mark/src/mp3_frame.py | 14 +++ mark/src/mp3_frame_factory.py | 29 +++++ mark/src/mp3_header_factory.py | 39 ++++--- mark/tests/test_mp3.py | 61 +--------- mark/tests/test_mp3_new.py | 41 +++++++ 12 files changed, 243 insertions(+), 214 deletions(-) create mode 100644 mark/src/mp3Factory.py create mode 100644 mark/src/mp3_file_io_factory.py create mode 100644 mark/src/mp3_frame.py create mode 100644 mark/src/mp3_frame_factory.py create mode 100644 mark/tests/test_mp3_new.py diff --git a/mark/.idea/inspectionProfiles/Project_Default.xml b/mark/.idea/inspectionProfiles/Project_Default.xml index 920d523..b10669a 100644 --- a/mark/.idea/inspectionProfiles/Project_Default.xml +++ b/mark/.idea/inspectionProfiles/Project_Default.xml @@ -8,5 +8,12 @@ + + + \ No newline at end of file diff --git a/mark/src/app.py b/mark/src/app.py index 5b47b95..52621b1 100644 --- a/mark/src/app.py +++ b/mark/src/app.py @@ -3,6 +3,8 @@ from Tools.scripts.pep384_macrocheck import parse_file from fastapi import FastAPI + +from mp3 import MP3 from mp3_file_io import MP3FileIo from fastapi.responses import StreamingResponse from fastapi.responses import Response @@ -16,7 +18,7 @@ async def health_check(): @app.get("/stream-mp3/{file_name:path}") -async def stream_mp3(file_name: str): +async def stream_mp3(file_name: str, speed: int = 1, updown: str = "down"): print(f"Current working directory: {os.getcwd()}") path = f"../resource/{file_name}" @@ -32,20 +34,24 @@ async def stream_mp3(file_name: str): finally: mp3_io.close() -# 추후 MP3 클래스를 사용하여 MP3 파일을 일부만 읽어오는 방법을 구현할 수 있습니다. - # mp3 = MP3(mp3_io) - # mp3.set_header() - # mp3.set_frame_size() - # mp3.set_frame_count() - # mp3.set_play_time() + mp3 = MP3(mp3_io) + mp3.set_header() + mp3.set_frame_size() + mp3.set_frame_count() + mp3.set_play_time() + + if updown == "down": + mp3 = mp3.change_speed_down(speed) + elif updown == "up": + mp3 = mp3.change_speed_up(speed) headers = { - "Content-Disposition": f"inline; filename={os.path.basename(path)}", + "Content-Disposition": f"inline;", "Content-Type": "audio/mpeg", - "Content-Length": str(mp3_io.get_size()) + "Content-Length": str(len(mp3.file_io.file_bytes)) } - return StreamingResponse(io.BytesIO(mp3_io.get_all()), headers=headers) + return StreamingResponse(io.BytesIO(mp3.file_io.file_bytes), headers=headers) if __name__ == "__main__": import uvicorn diff --git a/mark/src/main.py b/mark/src/main.py index 5290d9d..00b8b5f 100644 --- a/mark/src/main.py +++ b/mark/src/main.py @@ -13,5 +13,5 @@ print(mp3.header) print(mp3.frame_size) -print(mp3.frame_count) -print(mp3.play_time) \ No newline at end of file +print(mp3._frame_count) +print(mp3._play_time) \ No newline at end of file diff --git a/mark/src/mp3.py b/mark/src/mp3.py index 6b505f2..4f32995 100644 --- a/mark/src/mp3.py +++ b/mark/src/mp3.py @@ -1,96 +1,34 @@ -import mp3_header_factory +from mp3_file_io_factory import MP3FileIoFactory +from mp3_frame import MP3Frame class MP3: - def __init__(self, file_reader): - self.play_time = None - self.frame_size = 0 - self.frame_count = 0 - self.header = None - self.file_io = file_reader + def __init__(self): + self._frames = list[MP3Frame] + self._frame_count = 0 + self._play_time = 0 - def set_header(self): - header_bytes = self.file_io.get(4) - self.header = mp3_header_factory.MP3HeaderFactory.create(header_bytes) - - def get_header(self): - return self.header - - def set_frame_size(self): - self.frame_size = self.header.calc_frame_size() - - def get_frame_size(self): - return self.frame_size - - def set_frame_count(self): - offset = 4 # 태그 없어서 고정 offset 사용 - self.frame_count = (self.file_io.get_size() - offset) // self.frame_size + def set_frames(self, frames): + self._frames = frames + self._frame_count = len(frames) + self._frame_count = len(frames) + self._play_time = self._frame_count * 1152 / self._frames[0].header.sampling_rate def get_frame_count(self): - return self.set_frame_count - - def set_play_time(self): - frame_duration = 1152 / self.header.sampling_rate - self.play_time = self.frame_count * frame_duration + return self._frame_count def get_play_time(self): - return self.play_time - - def get_frame(self, index) -> bytes: - frame_size = self.header.calc_frame_size() - start = 4 + index * frame_size - end = start + frame_size - frame = self.file_io.get_bytes(start, end) - return frame - - def cut(self, start_time, end_time): - start_frame = int(start_time * self.header.sampling_rate / 1152) - end_frame = int(end_time * self.header.sampling_rate / 1152) - - frame_size = self.header.calc_frame_size() - start_byte = 4 + start_frame * frame_size - end_byte = end_frame * frame_size - - io = self.file_io.cut_frames(start_byte, end_byte) - return MP3(io) + return self._play_time - def change_speed_down(self, speed: int): - if speed <= 0: - raise ValueError("Speed must be greater than 0") - # 일단 전체 프레임을 배열로 저장한다 - frames = [] - for i in range(self.frame_count): - frames.append(self.get_frame(i)) - - new_frames = [] - for i in range(self.frame_count): - for _ in range(speed): - new_frames.append(frames[i]) - - io = self.file_io.change_frames(new_frames) - return MP3(io) - - def change_speed_up(self, speed: int): - if speed <= 0: - raise ValueError("Speed must be greater than 0") - - # 일단 전체 프레임을 배열로 저장한다 - frames = [] - for i in range(self.frame_count): - frames.append(self.get_frame(i)) - - new_frames = [] - - i = 0 - while i < self.frame_count: - print(f"Processing frame {i}") - new_frames.append(frames[i]) - i += speed + def save(self, file_path): + new_bytes = self.to_bytes() + MP3FileIoFactory.create_with_bytes(new_bytes).save(file_path) - io = self.file_io.change_frames(new_frames) - return MP3(io) + def to_bytes(self) -> bytes: + new_bytes = b'' - def save(self, file_path): - self.file_io.save(file_path) + for frame in self._frames: + new_bytes += frame.to_bytes() + return new_bytes diff --git a/mark/src/mp3Factory.py b/mark/src/mp3Factory.py new file mode 100644 index 0000000..73d4265 --- /dev/null +++ b/mark/src/mp3Factory.py @@ -0,0 +1,56 @@ +from mp3 import MP3 +from mp3_file_io import MP3FileIo +from mp3_frame_factory import Mp3FrameFactory + + +class MP3Factory: + @staticmethod + def create_by_file_path(file_path: str) -> MP3: + io = MP3FileIo() + io.open(file_path) + frames = Mp3FrameFactory.create(io) + io.close() + + return MP3Factory.create_by_frames(frames) + + @staticmethod + def create_by_frames(frames) -> MP3: + mp3 = MP3() + mp3.set_frames(frames) + return mp3 + + @staticmethod + def create_by_cut(mp3:MP3, start_time:int, end_time:int): + # 첫번째 헤더를 기준으로 시작 프레임과 끝 프레임을 계산한다 (CBR만 가능) + first_header = mp3._frames[0].header + + start_frame = int(start_time * first_header.sampling_rate / 1152) + end_frame = int(end_time * first_header.sampling_rate / 1152) + + new_frames = mp3._frames[start_frame:end_frame] + return MP3Factory.create_by_frames(new_frames) + + @staticmethod + def create_speed_down(mp3:MP3, speed: int): + if speed <= 0: + raise ValueError("Speed must be greater than 0") + + new_frames = [] + for i in range(mp3._frame_count): + for _ in range(speed): + new_frames.append(mp3._frames[i]) + + return MP3Factory.create_by_frames(new_frames) + + @staticmethod + def create_speed_up(mp3:MP3, speed: int): + if speed <= 0: + raise ValueError("Speed must be greater than 0") + + new_frames = [] + for i in range(mp3._frame_count): + if i % speed == 0: + frame = mp3._frames[i] + new_frames.append(frame) + + return MP3Factory.create_by_frames(new_frames) diff --git a/mark/src/mp3_file_io.py b/mark/src/mp3_file_io.py index 72b5509..e436528 100644 --- a/mark/src/mp3_file_io.py +++ b/mark/src/mp3_file_io.py @@ -1,83 +1,44 @@ import os.path -import mp3_header_factory - class MP3FileIo: def __init__(self): self.file_obj = None - self.bytes = None + self.file_bytes = None def file_exists(self, path): return os.path.exists(path) - def open(self, file_path): + def open(self, file_path) -> bool: try: self.file_obj = open(file_path, 'rb') except IOError as e: print(f"파일을 열 수 없습니다: {e}") - return + return False + return True def close(self): if self.file_obj is not None: self.file_obj.close() - def read_all(self): - self.bytes = self.file_obj.read() + def read(self, size): + return self.file_obj.read(size) def get(self, size): - return self.bytes[0:size] + return self.file_bytes[0:size] def get_bytes(self, start, end): - return self.bytes[start:end] + return self.file_bytes[start:end] def get_all(self): - return self.bytes + return self.file_bytes def get_size(self): - return len(self.bytes) - - def check_header(self): - try: - file_obj = open(self.file_path, 'rb') - header = file_obj.read(2) - file_obj.close() - - # Convert the header to an integer - header_int = int.from_bytes(header, byteorder='big') - - # MP3 Sync Word가(=11비트) 1로 시작하는지 확인한다. - # 0xFF = 1111 1111 - # 0xE0 = 1110 0000 - if (header_int & 0xFFE0) != 0xFFE0: - print("MP3 SYNC WORD not detected") - return False - return True - except IOError as e: - if isinstance(e, EOFError): - print(f"파일이 너무 작습니다: {e}") - else: - print(f"파일을 열 수 없습니다: {e}") - - return False - - def cut_frames(self, start_byte, end_byte): - io = MP3FileIo() - io.bytes = self.bytes[0:4] + self.bytes[start_byte:end_byte] - return io - - def change_frames(self, frames): - new_bytes = self.bytes[0:4] - - for frame in frames: - new_bytes += frame - io = MP3FileIo() - io.bytes = new_bytes - return io + return len(self.file_bytes) def save(self, file_path): try: file_obj = open(file_path, 'wb') - file_obj.write(self.bytes) + file_obj.write(self.file_bytes) file_obj.close() except IOError as e: print(f"파일을 저장할 수 없습니다: {e}") diff --git a/mark/src/mp3_file_io_factory.py b/mark/src/mp3_file_io_factory.py new file mode 100644 index 0000000..c8b9824 --- /dev/null +++ b/mark/src/mp3_file_io_factory.py @@ -0,0 +1,15 @@ +from mp3_file_io import MP3FileIo + + +class MP3FileIoFactory: + @staticmethod + def create_with_file(file_path: str) -> MP3FileIo: + io = MP3FileIo() + io.open(file_path) + return io + + @staticmethod + def create_with_bytes(file_bytes: bytes) -> MP3FileIo: + io = MP3FileIo() + io.file_bytes = file_bytes + return io diff --git a/mark/src/mp3_frame.py b/mark/src/mp3_frame.py new file mode 100644 index 0000000..2041bc8 --- /dev/null +++ b/mark/src/mp3_frame.py @@ -0,0 +1,14 @@ +from dataclasses import dataclass + +from mp3_header import MP3Header + + +@dataclass +class MP3Frame: + def __init__(self, header:MP3Header, header_bytes, data_bytes:bytes): + self.header = header + self.header_bytes = header_bytes + self.data_bytes = data_bytes + + def to_bytes(self): + return self.header_bytes + self.data_bytes diff --git a/mark/src/mp3_frame_factory.py b/mark/src/mp3_frame_factory.py new file mode 100644 index 0000000..11507c8 --- /dev/null +++ b/mark/src/mp3_frame_factory.py @@ -0,0 +1,29 @@ +from mp3_file_io import MP3FileIo +from mp3_frame import MP3Frame +from mp3_header_factory import MP3HeaderFactory + + +class Mp3FrameFactory: + @staticmethod + def create(io : MP3FileIo) -> list[MP3Frame]: + frames = [] + while True: + header_bytes = io.read(4) + if len(header_bytes) < 4: + break + + if MP3HeaderFactory.is_header(header_bytes) is False: + break + + header = MP3HeaderFactory.create(header_bytes) + frame_size = header.calc_frame_size() + + data_size = frame_size - 4 + data_bytes = io.read(data_size) + if len(data_bytes) < data_size: + break + + frame = MP3Frame(header, header_bytes, data_bytes) + frames.append(frame) + + return frames diff --git a/mark/src/mp3_header_factory.py b/mark/src/mp3_header_factory.py index 05d3560..34e15e2 100644 --- a/mark/src/mp3_header_factory.py +++ b/mark/src/mp3_header_factory.py @@ -1,9 +1,20 @@ +from warnings import catch_warnings + from mp3_header import MP3Header class MP3HeaderFactory: @classmethod - def create(cls, bytes): + + @staticmethod + def is_header(header_bytes: bytes) -> bool: + # 0xFFE0 + if header_bytes[0] == 0xFF and (header_bytes[1] & 0xE0) == 0xE0: + return True + return False + + @staticmethod + def create(header_bytes) -> MP3Header: versions = { 0: "2.5", 2: "2", @@ -57,19 +68,19 @@ def create(cls, bytes): 3: "CCIT J.17", } - version = versions[(bytes[1] & 0x18) >> 3] - layer = layers[(bytes[1] & 0x06) >> 1] - protection = (bytes[1] & 0x01) - bitrate = bitrate[(bytes[2] & 0xF0) >> 4] - sampling_rate = sampling_rates[(bytes[1] & 0x18) >> 3][(bytes[2] & 0x0C) >> 2] - padding = (bytes[2] & 0x02) >> 1 - private = (bytes[2] & 0x01) - channel_mode = channel_modes[(bytes[3] & 0xC0) >> 6] - mode_extension = mode_extensions[(bytes[3] & 0x30) >> 4] - copy_right = (bytes[3] & 0x08) >> 3 - original = (bytes[3] & 0x04) >> 2 - emphasis = emphases[(bytes[3] & 0x03)] + version = versions[(header_bytes[1] & 0x18) >> 3] + layer = layers[(header_bytes[1] & 0x06) >> 1] + protection = (header_bytes[1] & 0x01) + bitrate = bitrate[(header_bytes[2] & 0xF0) >> 4] + sampling_rate = sampling_rates[(header_bytes[1] & 0x18) >> 3][(header_bytes[2] & 0x0C) >> 2] + padding = (header_bytes[2] & 0x02) >> 1 + private = (header_bytes[2] & 0x01) + channel_mode = channel_modes[(header_bytes[3] & 0xC0) >> 6] + mode_extension = mode_extensions[(header_bytes[3] & 0x30) >> 4] + copy_right = (header_bytes[3] & 0x08) >> 3 + original = (header_bytes[3] & 0x04) >> 2 + emphasis = emphases[(header_bytes[3] & 0x03)] return MP3Header(version, layer, protection, bitrate, sampling_rate, padding, private, channel_mode, mode_extension, - copy_right, original, emphasis) + copy_right, original, emphasis) \ No newline at end of file diff --git a/mark/tests/test_mp3.py b/mark/tests/test_mp3.py index a70b68c..23c9c28 100644 --- a/mark/tests/test_mp3.py +++ b/mark/tests/test_mp3.py @@ -1,73 +1,24 @@ import unittest from mp3 import MP3 -from mp3_file_io import MP3FileIo +from mp3Factory import MP3Factory file_path = "../resource/input.mp3" class TestMp3(unittest.TestCase): def setUp(self): - reader = MP3FileIo() - reader.open(file_path) - reader.read_all() - reader.close() - - self.reader = reader - - def test_calc_frame(self): - mp3 = MP3(self.reader) - mp3.set_header() - mp3.set_frame_size() - - self.assertEqual(mp3.get_frame_size(), 1044) - - def test_calc_frame_size(self): - mp3 = MP3(self.reader) - mp3.set_header() - mp3.set_frame_size() - mp3.set_frame_count() - - self.assertEqual(mp3.get_frame_size(), 8980) - - def test_mp3_play_time(self): - mp3 = MP3(self.reader) - mp3.set_header() - mp3.set_frame_size() - mp3.set_frame_count() - mp3.set_play_time() - mp3_play_time = mp3.get_play_time() - - self.assertEqual(mp3_play_time, 234.5795918367347) + self.mp3 = MP3Factory.create_by_file_path(file_path) def test_mp3_cut(self): - mp3 = MP3(self.reader) - mp3.set_header() - mp3.set_frame_size() - mp3.set_frame_count() - mp3.set_play_time() - - output = mp3.cut(0, 20) - output.save("../resource/output.mp3") - + new_mp3 = MP3Factory.create_by_cut(self.mp3, 10, 20) + new_mp3.save("../resource/output_cut_10_20.mp3") def test_mp3_set_down_speed(self): - mp3 = MP3(self.reader) - mp3.set_header() - mp3.set_frame_size() - mp3.set_frame_count() - mp3.set_play_time() - - output = mp3.change_speed_down(2) + output = MP3Factory.create_speed_down(self.mp3,2) output.save("../resource/output_down_x2.mp3") def test_mp3_set_up_speed(self): - mp3 = MP3(self.reader) - mp3.set_header() - mp3.set_frame_size() - mp3.set_frame_count() - mp3.set_play_time() - - output = mp3.change_speed_up(2) + output = MP3Factory.create_speed_up(self.mp3, 2) output.save("../resource/output_up_x2.mp3") if __name__ == '__main__': diff --git a/mark/tests/test_mp3_new.py b/mark/tests/test_mp3_new.py new file mode 100644 index 0000000..ccd2846 --- /dev/null +++ b/mark/tests/test_mp3_new.py @@ -0,0 +1,41 @@ +import unittest + +from mp3_file_io import MP3FileIo +from mp3_frame import MP3Frame +from mp3_header_factory import MP3HeaderFactory + +# 삭제예정 +class TestMP3New(unittest.TestCase): + def test_all_situation(self): + # load mp3 file + io = MP3FileIo() + io.open("../resource/input.mp3") + + frames: list[MP3Frame] = [] + while True: + header_bytes = io.read(4) + if len(header_bytes) < 4: + break + + if MP3HeaderFactory.is_header(header_bytes) is False: + break + + header = MP3HeaderFactory.create(header_bytes) + frame_size = header.calc_frame_size() + + data_size = frame_size - 4 + data_bytes = io.read(data_size) + if len(data_bytes) < data_size: + break + + # Create the frame and add to the list + frame = MP3Frame(header, header_bytes, data_bytes) + frames.append(frame) + + io.close() + + len(frames) + + +if __name__ == '__main__': + unittest.main()