Skip to content

Commit

Permalink
feat: add support for MPEG-4 audio files
Browse files Browse the repository at this point in the history
bump to version v0.7.4
  • Loading branch information
NobeKanai committed Apr 29, 2024
1 parent e09bae7 commit 7319f86
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 12 deletions.
40 changes: 36 additions & 4 deletions dvtag/dvtag.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@

from mutagen.flac import FLAC
from mutagen.id3 import APIC, ID3, TALB, TCON, TDRC, TIT2, TPE1, TPE2, TPOS, TRCK, ID3NoHeaderError
from mutagen.mp4 import MP4, MP4Cover
from natsort import os_sorted
from PIL.Image import Image

from .doujinvoice import DoujinVoice
from .scrape import scrape, ParsingError
from .scrape import ParsingError, scrape
from .utils import extract_titles, get_audio_paths_list, get_image, get_picture, get_png_byte_arr

__all__ = ["tag"]
Expand Down Expand Up @@ -46,6 +47,32 @@ def tag_mp3s(mp3_paths: List[Path], dv: DoujinVoice, png_bytes_arr: BytesIO, dis
tags.delall("TRCK")


def tag_mp4s(files: List[Path], dv: DoujinVoice, png_bytes_arr: BytesIO, disc: Optional[int]):
cover = MP4Cover(png_bytes_arr.getvalue(), MP4Cover.FORMAT_PNG)

sorted = list(os_sorted(files))
titles = extract_titles(sorted_stems=[f.stem for f in sorted])

for trck, title, p in zip(range(1, len(sorted) + 1), titles, sorted):
tags = MP4(p)
tags.clear()

tags["\xa9alb"] = [dv.name]
tags["\xa9day"] = [dv.sale_date]
tags["\xa9nam"] = [title]
tags["aART"] = [dv.circle]
tags["covr"] = [cover]
tags["\xa9ART"] = [";".join(dv.seiyus)]
tags["\xa9gen"] = [";".join(dv.genres)]
tags["trkn"] = [(trck, 0)]
if disc:
tags["disk"] = [(disc, 0)]

if tags != MP4(p):
tags.save(p)
logging.info(f"Tagged <track: {trck}, disc: {disc}, title: '{title}'> to '{p.name}'")


def tag_flacs(files: List[Path], dv: DoujinVoice, image: Image, png_bytes_arr: BytesIO, disc: Optional[int]):
picture = get_picture(png_bytes_arr, image.width, image.height, image.mode)

Expand Down Expand Up @@ -76,8 +103,8 @@ def tag_flacs(files: List[Path], dv: DoujinVoice, image: Image, png_bytes_arr: B


def tag(basepath: Path, workno: str):
flac_paths_list, mp3_paths_list = get_audio_paths_list(basepath)
if not flac_paths_list and not mp3_paths_list:
flac_paths_list, m4a_paths_list, mp3_paths_list = get_audio_paths_list(basepath)
if not flac_paths_list and not m4a_paths_list and not mp3_paths_list:
return

try:
Expand All @@ -99,14 +126,19 @@ def tag(basepath: Path, workno: str):
png_bytes_arr = get_png_byte_arr(image)

disc = None
if len(flac_paths_list) + len(mp3_paths_list) > 1:
if len(flac_paths_list) + len(m4a_paths_list) + len(mp3_paths_list) > 1:
disc = 1

for flac_files in flac_paths_list:
tag_flacs(flac_files, dv, image, png_bytes_arr, disc)
if disc:
disc += 1

for m4a_files in m4a_paths_list:
tag_mp4s(m4a_files, dv, png_bytes_arr, disc)
if disc:
disc += 1

for mp3_files in mp3_paths_list:
tag_mp3s(mp3_files, dv, png_bytes_arr, disc)
if disc:
Expand Down
7 changes: 5 additions & 2 deletions dvtag/scrape.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,11 @@ def scrape(workno: str) -> DoujinVoice:

try:
data = json.loads(res[9:-1])
if data["count"] and (work := data["works"][0])["file_type"] == "audio":
image_url = work["thumb"].replace("media.dlsite.com/chobit", "file.chobit.cc", 1)
if data["count"]:
work = data["works"][0]
if work["file_type"] == "audio":
image_url = work["thumb"].replace("media.dlsite.com/chobit", "file.chobit.cc", 1)

# we may get a shorter, yet more accurate article title (with no promotion)
if work["work_name"] in name:
name = work["work_name"]
Expand Down
14 changes: 10 additions & 4 deletions dvtag/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,33 +40,39 @@ def _walk(basepath: Path):
yield f


def get_audio_paths_list(basepath: Path) -> Tuple[List[List[Path]], List[List[Path]]]:
def get_audio_paths_list(basepath: Path) -> Tuple[List[List[Path]], List[List[Path]], List[List[Path]]]:
"""Gets audio files(Path) from basepath recursively
Args:
basepath (Path): base path
Returns:
Tuple[List[List[Path]], List[List[Path]]]: flac paths list, mp3 paths list
Tuple[List[List[Path]], List[List[Path]], List[List[Path]]]: flac paths list, m4a paths list, mp3 paths list
"""
flac_paths_list: List[List[Path]] = []
m4a_paths_list: List[List[Path]] = []
mp3_paths_list: List[List[Path]] = []

for files in _walk(basepath):
mp3_paths: List[Path] = []
flac_paths: List[Path] = []
m4a_paths: List[Path] = []
mp3_paths: List[Path] = []
for file in files:
if file.suffix.lower() == ".flac":
flac_paths.append(file)
elif file.suffix.lower() == ".m4a":
m4a_paths.append(file)
elif file.suffix.lower() == ".mp3":
mp3_paths.append(file)

if len(flac_paths):
flac_paths_list.append(flac_paths)
if len(m4a_paths):
m4a_paths_list.append(m4a_paths)
if len(mp3_paths):
mp3_paths_list.append(mp3_paths)

return flac_paths_list, mp3_paths_list
return flac_paths_list, m4a_paths_list, mp3_paths_list


def get_workno(name: str) -> Optional[str]:
Expand Down
4 changes: 2 additions & 2 deletions setup.cfg
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
[metadata]
name = dvtag
version = 0.7.3
version = 0.7.4
author = Nobe Kanai
author_email = [email protected]
description = A tool for tagging your doujin voice library.
description = A command-line tool designed to tag your doujin voice library.
long_description = file: README.md
long_description_content_type = text/markdown
url = https://github.com/nobekanai/dvtag
Expand Down

0 comments on commit 7319f86

Please sign in to comment.