Skip to content

Commit

Permalink
Added option embed_cover, added documentation for covers
Browse files Browse the repository at this point in the history
  • Loading branch information
Dniel97 committed Mar 31, 2022
1 parent 2e87805 commit b775f6d
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 44 deletions.
26 changes: 26 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,32 @@ uses `album_format` in the `playlist_format` folder
```
to the corresponding path

### Global/Covers

```json5
{
"embed_cover": true,
"main_compression": "high",
"main_resolution": 1400,
"save_external": false,
"external_format": "png",
"external_compression": "low",
"external_resolution": 3000,
"save_animated_cover": true
}
```

| Option | Info |
|----------------------|------------------------------------------------------------------------------------------|
| embed_cover | Enable it to embed the album cover inside every track |
| main_compression | Compression of the main cover |
| main_resolution | Resolution (in pixels) of the cover of the module used |
| save_external | Enable it to save the cover from a third party cover module |
| external_format | Format of the third party cover, supported values: `jpg`, `png`, `webp` |
| external_compression | Compression of the third party cover, supported values: `low`, `high` |
| external_resolution | Resolution (in pixels) of the third party cover |
| save_animated_cover | Enable saving the animated cover when supported from the module (often in MPEG-4 format) |

### Global/Codecs

```json5
Expand Down
1 change: 1 addition & 0 deletions orpheus/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ def __init__(self, private_mode=False):
"save_synced_lyrics": True
},
"covers": {
"embed_cover": True,
"main_compression": "high",
"main_resolution": 1400,
"save_external": False,
Expand Down
10 changes: 7 additions & 3 deletions orpheus/music_downloader.py
Original file line number Diff line number Diff line change
Expand Up @@ -538,10 +538,14 @@ def download_track(self, track_id, album_location='', main_artist='', track_inde
# Finally tag file
self.print('Tagging file')
try:
tag_file(track_location, cover_temp_location, track_info, credits_list, embedded_lyrics, container)
if old_track_location: tag_file(old_track_location, cover_temp_location, track_info, credits_list, embedded_lyrics, old_container)
tag_file(track_location, cover_temp_location if self.global_settings['covers']['embed_cover'] else None,
track_info, credits_list, embedded_lyrics, container)
if old_track_location:
tag_file(old_track_location, cover_temp_location if self.global_settings['covers']['embed_cover'] else None,
track_info, credits_list, embedded_lyrics, old_container)
except TagSavingFailure:
self.print('Tagging failed, tags saved to text file')
if delete_cover: silentremove(cover_temp_location)
if delete_cover:
silentremove(cover_temp_location)

self.print(f'=== Track {track_id} downloaded ===', drop_level=1)
88 changes: 47 additions & 41 deletions orpheus/tagging.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
import base64, logging
import base64
import logging
from dataclasses import asdict

from PIL import Image
from mutagen.easyid3 import EasyID3
from mutagen.easymp4 import EasyMP4
from mutagen.flac import FLAC, Picture
from mutagen.id3 import PictureType, APIC, USLT, TDAT
from mutagen.mp3 import EasyMP3
from mutagen.oggopus import OggOpus
from mutagen.oggvorbis import OggVorbis
from mutagen.mp4 import MP4Cover
from mutagen.mp4 import MP4Tags
from mutagen.id3 import PictureType, APIC, USLT, TDRL, TDAT
from PIL import Image
from mutagen.oggopus import OggOpus
from mutagen.oggvorbis import OggVorbis

from utils.models import ContainerEnum, TrackInfo
from utils.exceptions import *
from utils.models import ContainerEnum, TrackInfo

# Needed for Windows tagging support
MP4Tags._padding = 0
Expand Down Expand Up @@ -157,41 +158,46 @@ def tag_file(file_path: str, image_path: str, track_info: TrackInfo, credits_lis
tagger['REPLAYGAIN_TRACK_GAIN'] = str(track_info.tags.replay_gain)
tagger['REPLAYGAIN_TRACK_PEAK'] = str(track_info.tags.replay_peak)

with open(image_path, 'rb') as c: data = c.read()
picture = Picture()
picture.data = data

# Check if cover is smaller than 16MB
if len(picture.data) < picture._MAX_SIZE:
if container == ContainerEnum.flac:
picture.type = PictureType.COVER_FRONT
picture.mime = u'image/jpeg'
tagger.add_picture(picture)
elif container == ContainerEnum.m4a:
tagger['covr'] = [MP4Cover(data, imageformat=MP4Cover.FORMAT_JPEG)]
elif container == ContainerEnum.mp3:
# Never access protected attributes, too bad!
tagger.tags._EasyID3__id3._DictProxy__dict['APIC'] = APIC(
encoding=3, # UTF-8
mime='image/jpeg',
type=3, # album art
desc='Cover', # name
data=data
)
# If you want to have a cover in only a few applications, then this technically works for Opus
elif container in {ContainerEnum.ogg, ContainerEnum.opus}:
im = Image.open(image_path)
width, height = im.size
picture.type = 17
picture.desc = u'Cover Art'
picture.mime = u'image/jpeg'
picture.width = width
picture.height = height
picture.depth = 24
encoded_data = base64.b64encode(picture.write())
tagger['metadata_block_picture'] = [encoded_data.decode('ascii')]
else:
print(f'\tCover file size is too large, only {(picture._MAX_SIZE / 1024 ** 2):.2f}MB are allowed. Track will not have cover saved.')
# only embed the cover when embed_cover is set to True
if image_path:
with open(image_path, 'rb') as c:
data = c.read()
picture = Picture()
picture.data = data

# Check if cover is smaller than 16MB
if len(picture.data) < picture._MAX_SIZE:
if container == ContainerEnum.flac:
picture.type = PictureType.COVER_FRONT
picture.mime = u'image/jpeg'
tagger.add_picture(picture)
elif container == ContainerEnum.m4a:
tagger['covr'] = [MP4Cover(data, imageformat=MP4Cover.FORMAT_JPEG)]
elif container == ContainerEnum.mp3:
# Never access protected attributes, too bad!
tagger.tags._EasyID3__id3._DictProxy__dict['APIC'] = APIC(
encoding=3, # UTF-8
mime='image/jpeg',
type=3, # album art
desc='Cover', # name
data=data
)
# If you want to have a cover in only a few applications, then this technically works for Opus
elif container in {ContainerEnum.ogg, ContainerEnum.opus}:
im = Image.open(image_path)
width, height = im.size
picture.type = 17
picture.desc = u'Cover Art'
picture.mime = u'image/jpeg'
picture.width = width
picture.height = height
picture.depth = 24
encoded_data = base64.b64encode(picture.write())
tagger['metadata_block_picture'] = [encoded_data.decode('ascii')]
else:
print(f'\tCover file size is too large, only {(picture._MAX_SIZE / 1024 ** 2):.2f}MB are allowed. Track '
f'will not have cover saved.')

try:
tagger.save(file_path, v1=2, v2_version=3, v23_sep=None) if container == ContainerEnum.mp3 else tagger.save()
except:
Expand Down

0 comments on commit b775f6d

Please sign in to comment.