From ce92747d8996d1362cf764d7b542cd5bd37d345e Mon Sep 17 00:00:00 2001 From: Eliot Berriot <contact@eliotberriot.com> Date: Sat, 12 May 2018 12:06:14 +0200 Subject: [PATCH] Fix #157: Can now import and play flac files If you ever need an empty flac file with metadata again: 1. Get a flac file (like https://archive.org/download/NineInchNailsTheSlip24bit96khz/01999999.flac) 2. Tag it with Musicbrainz Picard 3. Truncate it, keeping only tags with `ffmpeg -i in.flac -ss 0 -to 0.001 out.flac` Thanks @HgO for the trick! --- api/funkwhale_api/music/metadata.py | 40 +++++++++++++++++++++++++++- api/funkwhale_api/music/utils.py | 1 + api/tests/music/sample.flac | Bin 0 -> 9793 bytes api/tests/music/test_metadata.py | 17 ++++++++++++ changes/changelog.d/157.feature | 1 + front/src/audio/formats.js | 3 ++- 6 files changed, 60 insertions(+), 2 deletions(-) create mode 100644 api/tests/music/sample.flac create mode 100644 changes/changelog.d/157.feature diff --git a/api/funkwhale_api/music/metadata.py b/api/funkwhale_api/music/metadata.py index a20069783..494256711 100644 --- a/api/funkwhale_api/music/metadata.py +++ b/api/funkwhale_api/music/metadata.py @@ -28,6 +28,13 @@ def get_id3_tag(f, k): raise TagNotFound(k) +def get_flac_tag(f, k): + try: + return f.get(k)[0] + except (KeyError, IndexError): + raise TagNotFound(k) + + def get_mp3_recording_id(f, k): try: return [ @@ -121,7 +128,38 @@ CONF = { 'getter': get_mp3_recording_id, }, } - } + }, + 'FLAC': { + 'getter': get_flac_tag, + 'fields': { + 'track_number': { + 'field': 'tracknumber', + 'to_application': convert_track_number + }, + 'title': { + 'field': 'title' + }, + 'artist': { + 'field': 'artist' + }, + 'album': { + 'field': 'album' + }, + 'date': { + 'field': 'date', + 'to_application': lambda v: arrow.get(str(v)).date() + }, + 'musicbrainz_albumid': { + 'field': 'musicbrainz_albumid' + }, + 'musicbrainz_artistid': { + 'field': 'musicbrainz_artistid' + }, + 'musicbrainz_recordingid': { + 'field': 'musicbrainz_trackid' + }, + } + }, } diff --git a/api/funkwhale_api/music/utils.py b/api/funkwhale_api/music/utils.py index 49a639303..329a99bed 100644 --- a/api/funkwhale_api/music/utils.py +++ b/api/funkwhale_api/music/utils.py @@ -66,6 +66,7 @@ def compute_status(jobs): AUDIO_EXTENSIONS_AND_MIMETYPE = [ ('ogg', 'audio/ogg'), ('mp3', 'audio/mpeg'), + ('flac', 'audio/flac'), ] EXTENSION_TO_MIMETYPE = {ext: mt for ext, mt in AUDIO_EXTENSIONS_AND_MIMETYPE} diff --git a/api/tests/music/sample.flac b/api/tests/music/sample.flac new file mode 100644 index 0000000000000000000000000000000000000000..6eff1c06e43f6f536c2d810d0d059cc6af319f5e GIT binary patch literal 9793 zcmeH{TZr6b6vtz`QoOF)+RL^@vr7vF%}#EUNnB&iWU{*%Gs&1_XtzGJ-{jH>%_hTS zwxDmyiuFwpi-HO&xDQrAg!<rvs1HS0ygjt|BCaC!RS@*SI-X=N?v7OOQTRe8lbrK? zIp_S&|0Fb!N)W^(Ns#dOIh^~uJG*du=5Xz~;Jtd{{kHee^6EQpTpl5Aow*Af209;> zD^q1*ilLbYz>phVTTve~TaBt_%gkOds8*wCIq>B6f}~H{!Ba`v+g&)C^R_-a=gKTi zi)0cdqhPHmu2vW*x(w&8+@w3IDl@mi?YySgg*OkCzgagFSGP==E`gzGTeX%7p_CXU zWFuXS{h&9k^!t&wn2~mxWz$=eDALtkLz5**dJukjx(4K=>W;fD-7#?3nxQF<rdlo2 zwdduNC+-BJYq^S%=jX`G!F;z;)ePC~1f;nb$E2F}x@iyfqcpjDV|4)tmeY@brO|S9 zwQ4K6dFr%cR9g+jb|JW4liQUr^jQ>AJR`!T9k5i}_Zf<1L$S?^0>k+z&ma%JfqRpG zkrsqFJ``fTh9U)s!7)rIm1&=nq%u!&<uIfqn)fJy6A+7N!DA~z-V?>qO}R?bj5=dA z8;{?goBmGLv20g1qa+~p#OshIisEcPEU}=ux(Rr;ck~W$IjXHUUD-hW<Y9O;bX7AQ zP44vj-G@pguNMHa^MRKxETl;`mG;h-;>Zh<EXYdjC#l4vGF0NG=+a_V5@G*8C_-%v z+b&mpUZ4;ou@o;!0fi(cq$)lVgo;EX#$)!u-gP97tGF#kPQx(rA`~A2&z2I0%PVxP zK<lm9b@p>`PqGyT_Gu=Rt^KPC8<E#RK}@<JlAxDMqX<?A$BCn^1eR?@{TEg2$v0~? zU6E_i*{F|VvJv<Z+M;21zNyJ5ZZ9t6bJ);N4keo}-RR!t#3^8GYW9p}H(+@^%{t^v zF9@<=+D_Y1Le4~qcWzpVgDgXd-%E4x_oF1*Hgfr!b;nlamgA~rS`@^Jz~qX^WxTH1 zyen&CFpT{sa-OxVRufuYmL$5(av>$~3`=nV438vA9))<3V?rLJ9#)3svN;NL$b}pi zP@+$J6dwo@C6+mf^4fldW_*}IR?G){EwP(Pe%(8qcP^J8@lyC2f#$b-G@mZMwcy1E zCV&ZG0+;|MfC*p%m;fe#319-4049J5U;>x`CV&ZG0+;|MfC*p%m;fe#319-4049J5 z{I3ZNem{4KI6Y?$27eI5&cWaYLEJJZj<vF`XUCiIj%!ytD_@o;X6yaQF@IHmR2`{) zJ%&i_t&6)ayh1#4U+DvM>cq=$9{Ba*75AfeU;8r{y<Plf*U$Eq8{*QvubW#5-BUb_ z5X25RudiONfAPez7vEq0<>MdD)UQn*`*sg696fsE`M1^a@xvEZjPIFGx}P<led%iB k)gPDkz3}NAKk?J}=)nWueYHGZH|CFAnsC__iCp^dFDd@T`Tzg` literal 0 HcmV?d00001 diff --git a/api/tests/music/test_metadata.py b/api/tests/music/test_metadata.py index 342bc99b8..3f1ea9177 100644 --- a/api/tests/music/test_metadata.py +++ b/api/tests/music/test_metadata.py @@ -40,3 +40,20 @@ def test_can_get_metadata_from_id3_mp3_file(field, value): data = metadata.Metadata(path) assert data.get(field) == value + + +@pytest.mark.parametrize('field,value', [ + ('title', '999,999'), + ('artist', 'Nine Inch Nails'), + ('album', 'The Slip'), + ('date', datetime.date(2008, 5, 5)), + ('track_number', 1), + ('musicbrainz_albumid', uuid.UUID('12b57d46-a192-499e-a91f-7da66790a1c1')), + ('musicbrainz_recordingid', uuid.UUID('30f3f33e-8d0c-4e69-8539-cbd701d18f28')), + ('musicbrainz_artistid', uuid.UUID('b7ffd2af-418f-4be2-bdd1-22f8b48613da')), +]) +def test_can_get_metadata_from_flac_file(field, value): + path = os.path.join(DATA_DIR, 'sample.flac') + data = metadata.Metadata(path) + + assert data.get(field) == value diff --git a/changes/changelog.d/157.feature b/changes/changelog.d/157.feature new file mode 100644 index 000000000..0560541b5 --- /dev/null +++ b/changes/changelog.d/157.feature @@ -0,0 +1 @@ +Can now import and play flac files (#157) diff --git a/front/src/audio/formats.js b/front/src/audio/formats.js index f6e2157a1..a4c2ecf0e 100644 --- a/front/src/audio/formats.js +++ b/front/src/audio/formats.js @@ -5,6 +5,7 @@ export default { ], formatsMap: { 'audio/ogg': 'ogg', - 'audio/mpeg': 'mp3' + 'audio/mpeg': 'mp3', + 'audio/flac': 'flac' } } -- GitLab