diff --git a/api/funkwhale_api/music/factories.py b/api/funkwhale_api/music/factories.py
index 1df949904db992e2cd295d02e4acbfed9d212627..412e2f798835579217f6fa84b35e926d59baaba9 100644
--- a/api/funkwhale_api/music/factories.py
+++ b/api/funkwhale_api/music/factories.py
@@ -54,6 +54,10 @@ class TrackFileFactory(factory.django.DjangoModelFactory):
     audio_file = factory.django.FileField(
         from_path=os.path.join(SAMPLES_PATH, 'test.ogg'))
 
+    bitrate = None
+    size = None
+    duration = None
+
     class Meta:
         model = 'music.TrackFile'
 
diff --git a/api/funkwhale_api/music/models.py b/api/funkwhale_api/music/models.py
index 0ab8528900906814e4e5459d35adb4156612d1db..7c5fbe9a6a1195c56f55f88c7a92848e4abf42c8 100644
--- a/api/funkwhale_api/music/models.py
+++ b/api/funkwhale_api/music/models.py
@@ -479,6 +479,24 @@ class TrackFile(models.Model):
             return
         return os.path.splitext(self.audio_file.name)[-1].replace('.', '', 1)
 
+    def get_file_size(self):
+        if self.audio_file:
+            return self.audio_file.size
+
+        if self.source.startswith('file://'):
+            return os.path.getsize(self.source.replace('file://', '', 1))
+
+        if self.library_track and self.library_track.audio_file:
+            return self.library_track.audio_file.size
+
+    def get_audio_file(self):
+        if self.audio_file:
+            return self.audio_file.open()
+        if self.source.startswith('file://'):
+            return open(self.source.replace('file://', '', 1), 'rb')
+        if self.library_track and self.library_track.audio_file:
+            return self.library_track.audio_file.open()
+
     def save(self, **kwargs):
         if not self.mimetype and self.audio_file:
             self.mimetype = utils.guess_mimetype(self.audio_file)
diff --git a/api/funkwhale_api/music/serializers.py b/api/funkwhale_api/music/serializers.py
index 9dfc9147872871b0f0ba500c213f812b79bad8d7..d9d48496e487395be4ff0516b64f43b1074f37c1 100644
--- a/api/funkwhale_api/music/serializers.py
+++ b/api/funkwhale_api/music/serializers.py
@@ -27,6 +27,7 @@ class SimpleArtistSerializer(serializers.ModelSerializer):
 
 class ArtistSerializer(serializers.ModelSerializer):
     tags = TagSerializer(many=True, read_only=True)
+
     class Meta:
         model = models.Artist
         fields = ('id', 'mbid', 'name', 'tags', 'creation_date')
@@ -40,11 +41,21 @@ class TrackFileSerializer(serializers.ModelSerializer):
         fields = (
             'id',
             'path',
-            'duration',
             'source',
             'filename',
             'mimetype',
-            'track')
+            'track',
+            'duration',
+            'mimetype',
+            'bitrate',
+            'size',
+        )
+        read_only_fields = [
+            'duration',
+            'mimetype',
+            'bitrate',
+            'size',
+        ]
 
     def get_path(self, o):
         url = o.path
diff --git a/api/funkwhale_api/music/tasks.py b/api/funkwhale_api/music/tasks.py
index bad0006aa98520e2afac00aad8d5466bde2b8934..a6d76b962b288e6d530a8ff66b120f14ebdbaf85 100644
--- a/api/funkwhale_api/music/tasks.py
+++ b/api/funkwhale_api/music/tasks.py
@@ -134,6 +134,19 @@ def _do_import(import_job, replace=False, use_acoustid=True):
         # in place import, we set mimetype from extension
         path, ext = os.path.splitext(import_job.source)
         track_file.mimetype = music_utils.get_type_from_ext(ext)
+    audio_file = track_file.get_audio_file()
+    if audio_file:
+        with audio_file as f:
+            audio_data = music_utils.get_audio_file_data(f)
+        track_file.duration = int(audio_data['length'])
+        track_file.bitrate = audio_data['bitrate']
+        track_file.size = track_file.get_file_size()
+    else:
+        lt = track_file.library_track
+        if lt:
+            track_file.duration = lt.get_metadata('length')
+            track_file.size = lt.get_metadata('size')
+            track_file.bitrate = lt.get_metadata('bitrate')
     track_file.save()
     import_job.status = 'finished'
     import_job.track_file = track_file
diff --git a/api/funkwhale_api/music/utils.py b/api/funkwhale_api/music/utils.py
index 0c73f408fb1e83ce848170e89e46dbe6d942056e..04ca208d6a94c25aec3bea2b9734ac3b711c35cc 100644
--- a/api/funkwhale_api/music/utils.py
+++ b/api/funkwhale_api/music/utils.py
@@ -1,5 +1,6 @@
 import magic
 import mimetypes
+import mutagen
 import re
 
 from django.db.models import Q
@@ -82,3 +83,12 @@ def get_type_from_ext(extension):
         # we remove leading dot
         extension = extension[1:]
     return EXTENSION_TO_MIMETYPE.get(extension)
+
+
+def get_audio_file_data(f):
+    data = mutagen.File(f)
+    d = {}
+    d['bitrate'] = data.info.bitrate
+    d['length'] = data.info.length
+
+    return d
diff --git a/api/tests/music/test_import.py b/api/tests/music/test_import.py
index c7b40fb16e9ebc50e33060b88c0c82947e808451..8453dca8407ad551f70930a00d5e16494560ab38 100644
--- a/api/tests/music/test_import.py
+++ b/api/tests/music/test_import.py
@@ -1,4 +1,5 @@
 import json
+import os
 import pytest
 
 from django.urls import reverse
@@ -7,6 +8,8 @@ from funkwhale_api.federation import actors
 from funkwhale_api.federation import serializers as federation_serializers
 from funkwhale_api.music import tasks
 
+DATA_DIR = os.path.dirname(os.path.abspath(__file__))
+
 
 def test_create_import_can_bind_to_request(
         artists, albums, mocker, factories, superuser_api_client):
@@ -40,11 +43,20 @@ def test_create_import_can_bind_to_request(
     assert batch.import_request == request
 
 
-def test_import_job_from_federation_no_musicbrainz(factories):
+def test_import_job_from_federation_no_musicbrainz(factories, mocker):
+    mocker.patch(
+        'funkwhale_api.music.utils.get_audio_file_data',
+        return_value={'bitrate': 24, 'length': 666})
+    mocker.patch(
+        'funkwhale_api.music.models.TrackFile.get_file_size',
+        return_value=42)
     lt = factories['federation.LibraryTrack'](
         artist_name='Hello',
         album_title='World',
         title='Ping',
+        metadata__length=42,
+        metadata__bitrate=43,
+        metadata__size=44,
     )
     job = factories['music.ImportJob'](
         federation=True,
@@ -56,6 +68,9 @@ def test_import_job_from_federation_no_musicbrainz(factories):
 
     tf = job.track_file
     assert tf.mimetype == lt.audio_mimetype
+    assert tf.duration == 42
+    assert tf.bitrate == 43
+    assert tf.size == 44
     assert tf.library_track == job.library_track
     assert tf.track.title == 'Ping'
     assert tf.track.artist.name == 'Hello'
@@ -234,13 +249,13 @@ def test_import_batch_notifies_followers(
 
 
 def test__do_import_in_place_mbid(factories, tmpfile):
-    path = '/test.ogg'
+    path = os.path.join(DATA_DIR, 'test.ogg')
     job = factories['music.ImportJob'](
-        in_place=True, source='file:///test.ogg')
+        in_place=True, source='file://{}'.format(path))
 
     track = factories['music.Track'](mbid=job.mbid)
     tf = tasks._do_import(job, use_acoustid=False)
 
     assert bool(tf.audio_file) is False
-    assert tf.source == 'file:///test.ogg'
+    assert tf.source == 'file://{}'.format(path)
     assert tf.mimetype == 'audio/ogg'
diff --git a/api/tests/music/test_models.py b/api/tests/music/test_models.py
index d76c09a01e41a4e63416e5b4da7a1f07a24d9515..e926d07fa2be7c367b50e53acbc72666eca8b06b 100644
--- a/api/tests/music/test_models.py
+++ b/api/tests/music/test_models.py
@@ -85,3 +85,28 @@ def test_track_file_file_name(factories):
     tf = factories['music.TrackFile'](audio_file__from_path=path)
 
     assert tf.filename == tf.track.full_name + '.mp3'
+
+
+def test_track_get_file_size(factories):
+    name = 'test.mp3'
+    path = os.path.join(DATA_DIR, name)
+    tf = factories['music.TrackFile'](audio_file__from_path=path)
+
+    assert tf.get_file_size() == 297745
+
+
+def test_track_get_file_size_federation(factories):
+    tf = factories['music.TrackFile'](
+        federation=True,
+        library_track__with_audio_file=True)
+
+    assert tf.get_file_size() == tf.library_track.audio_file.size
+
+
+def test_track_get_file_size_in_place(factories):
+    name = 'test.mp3'
+    path = os.path.join(DATA_DIR, name)
+    tf = factories['music.TrackFile'](
+        in_place=True, source='file://{}'.format(path))
+
+    assert tf.get_file_size() == 297745
diff --git a/api/tests/music/test_tasks.py b/api/tests/music/test_tasks.py
index ddbc4ba9a2c7407bd067dc2799f499654cbb004c..c5839432bf128a3a03387bb2894d8ad56615594b 100644
--- a/api/tests/music/test_tasks.py
+++ b/api/tests/music/test_tasks.py
@@ -62,6 +62,9 @@ def test_import_job_can_run_with_file_and_acoustid(
             'score': 0.860825}],
         'status': 'ok'
     }
+    mocker.patch(
+        'funkwhale_api.music.utils.get_audio_file_data',
+        return_value={'bitrate': 42, 'length': 43})
     mocker.patch(
         'funkwhale_api.musicbrainz.api.artists.get',
         return_value=artists['get']['adhesive_wombat'])
@@ -82,7 +85,9 @@ def test_import_job_can_run_with_file_and_acoustid(
 
     with open(path, 'rb') as f:
         assert track_file.audio_file.read() == f.read()
-    assert track_file.duration == 268
+    assert track_file.bitrate == 42
+    assert track_file.duration == 43
+    assert track_file.size == os.path.getsize(path)
     # audio file is deleted from import job once persisted to audio file
     assert not job.audio_file
     assert job.status == 'finished'
diff --git a/api/tests/music/test_utils.py b/api/tests/music/test_utils.py
index 0a4f4b99424c34557fb846866b6e1b2958244a88..12b381a997c59ea85ebf1239024b1d3f288e2cdf 100644
--- a/api/tests/music/test_utils.py
+++ b/api/tests/music/test_utils.py
@@ -1,5 +1,10 @@
+import os
+import pytest
+
 from funkwhale_api.music import utils
 
+DATA_DIR = os.path.dirname(os.path.abspath(__file__))
+
 
 def test_guess_mimetype_try_using_extension(factories, mocker):
     mocker.patch(
@@ -17,3 +22,16 @@ def test_guess_mimetype_try_using_extension_if_fail(factories, mocker):
         audio_file__filename='test.mp3')
 
     assert utils.guess_mimetype(f.audio_file) == 'audio/mpeg'
+
+
+@pytest.mark.parametrize('name, expected', [
+    ('sample.flac', {'bitrate': 1608000, 'length': 0.001}),
+    ('test.mp3', {'bitrate': 8000, 'length': 267.70285714285717}),
+    ('test.ogg', {'bitrate': 128000, 'length': 229.18304166666667}),
+])
+def test_get_audio_file_data(name, expected):
+    path = os.path.join(DATA_DIR, name)
+    with open(path, 'rb') as f:
+        result = utils.get_audio_file_data(f)
+
+    assert result == expected