Skip to content

Commit 0d34837

Browse files
authored
Merge pull request #194 from freelawproject/feat-adds-helper-method-to-downsize-audio-files
2 parents d959044 + 2114dc8 commit 0d34837

File tree

5 files changed

+73
-9
lines changed

5 files changed

+73
-9
lines changed

README.md

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -311,14 +311,25 @@ from courts across the country and standardizes the format for our end users.
311311

312312
This endpoint also adds the SEAL of the court to the MP3 file and updates the metadata to reflect our updates.
313313

314-
This isn't the cleanest of CURLs because we have to convert the large JSON file to a query string, but for proof of concept here is the result
315-
316314
curl 'http://localhost:5050/convert/audio/mp3/?audio_data=%7B%22court_full_name%22%3A+%22Testing+Supreme+Court%22%2C+%22court_short_name%22%3A+%22Testing+Supreme+Court%22%2C+%22court_pk%22%3A+%22test%22%2C+%22court_url%22%3A+%22http%3A%2F%2Fwww.example.com%2F%22%2C+%22docket_number%22%3A+%22docket+number+1+005%22%2C+%22date_argued%22%3A+%222020-01-01%22%2C+%22date_argued_year%22%3A+%222020%22%2C+%22case_name%22%3A+%22SEC+v.+Frank+J.+Custable%2C+Jr.%22%2C+%22case_name_full%22%3A+%22case+name+full%22%2C+%22case_name_short%22%3A+%22short%22%2C+%22download_url%22%3A+%22http%3A%2F%2Fmedia.ca7.uscourts.gov%2Fsound%2Fexternal%2Fgw.15-1442.15-1442_07_08_2015.mp3%22%7D' \
317315
-X 'POST' \
318316
-F "file=@doctor/test_assets/1.wma"
319317

320318
This returns the audio file as a file response.
321319

320+
### Endpoint: /convert/audio/ogg/
321+
322+
This endpoint takes an audio file and converts it to an OGG file. The conversion process downsizes files by using
323+
a single audio channel and fixing the sampling rate to 8 kHz.
324+
325+
This endpoint also optimizes the output for voice over IP applications.
326+
327+
curl 'http://localhost:5050/convert/audio/ogg/' \
328+
-X 'POST' \
329+
-F "file=@doctor/test_assets/1.wma"
330+
331+
This returns the audio file as a file response.
332+
322333

323334
## Testing
324335

doctor/forms.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ class AudioForm(BaseAudioFile):
4444
audio_data = forms.JSONField(label="audio-data", required=False)
4545

4646
def clean(self):
47-
self.cleaned_data["fp"] = f"/tmp/audio_{uuid.uuid4().hex}.mp3"
47+
self.cleaned_data["fp"] = f"/tmp/audio_{uuid.uuid4().hex}"
4848
if self.cleaned_data.get("file", None):
4949
filename = self.cleaned_data["file"].name
5050
self.cleaned_data["extension"] = filename.split(".")[-1]

doctor/tasks.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -479,6 +479,47 @@ def convert_to_mp3(output_path: AnyStr, media: Any) -> None:
479479
return output_path
480480

481481

482+
def convert_to_ogg(output_path: AnyStr, media: Any) -> None:
483+
"""Converts audio data to the ogg format (.ogg)
484+
485+
This function uses ffmpeg to convert the audio data provided in `media` to
486+
the ogg format with the following specifications:
487+
488+
* Single audio channel (`-ac 1`)
489+
* 8 kHz sampling rate (`-b:a 8k`)
490+
* Optimized for voice over IP applications (`-application voip`)
491+
492+
:param output_path: Audio file bytes sent to Doctor
493+
:param media: Temporary filepath for output of audioprocess
494+
:return:
495+
"""
496+
av_command = [
497+
"ffmpeg",
498+
"-i",
499+
"/dev/stdin",
500+
"-vn",
501+
"-map_metadata",
502+
"-1",
503+
"-ac",
504+
"1",
505+
"-c:a",
506+
"libopus",
507+
"-b:a",
508+
"8k",
509+
"-application",
510+
"voip",
511+
"-f",
512+
"ogg",
513+
output_path,
514+
]
515+
516+
ffmpeg_cmd = subprocess.Popen(
517+
av_command, stdin=subprocess.PIPE, stdout=subprocess.PIPE, shell=False
518+
)
519+
ffmpeg_cmd.communicate(media.read())
520+
return output_path
521+
522+
482523
def set_mp3_meta_data(
483524
audio_data: Dict, mp3_path: AnyStr
484525
) -> eyed3.core.AudioFile:

doctor/urls.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from django.urls import path
1+
from django.urls import path, re_path
22

33
from . import views
44

@@ -23,7 +23,9 @@
2323
views.make_png_thumbnails_from_range,
2424
name="thumbnails",
2525
),
26-
path("convert/audio/mp3/", views.convert_audio, name="convert-audio"),
26+
re_path(
27+
"convert/audio/(mp3|ogg)/", views.convert_audio, name="convert-audio"
28+
),
2729
path("utils/page-count/pdf/", views.page_count, name="page_count"),
2830
path("utils/mime-type/", views.extract_mime_type, name="mime_type"),
2931
path(

doctor/views.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
from doctor.tasks import (
3535
convert_tiff_to_pdf_bytes,
3636
convert_to_mp3,
37+
convert_to_ogg,
3738
download_images,
3839
extract_from_doc,
3940
extract_from_docx,
@@ -367,8 +368,11 @@ def fetch_audio_duration(request) -> HttpResponse:
367368
return HttpResponse(str(e))
368369

369370

370-
def convert_audio(request) -> Union[FileResponse, HttpResponse]:
371-
"""Convert audio file to MP3 and update metadata on mp3.
371+
def convert_audio(
372+
request, output_format: str
373+
) -> Union[FileResponse, HttpResponse]:
374+
"""Converts an uploaded audio file to the specified output format and
375+
updates its metadata.
372376
373377
:return: Converted audio
374378
"""
@@ -378,8 +382,14 @@ def convert_audio(request) -> Union[FileResponse, HttpResponse]:
378382
filepath = form.cleaned_data["fp"]
379383
media_file = form.cleaned_data["file"]
380384
audio_data = {k: v[0] for k, v in dict(request.GET).items()}
381-
convert_to_mp3(filepath, media_file)
382-
set_mp3_meta_data(audio_data, filepath)
385+
match output_format:
386+
case "mp3":
387+
convert_to_mp3(filepath, media_file)
388+
set_mp3_meta_data(audio_data, filepath)
389+
case "ogg":
390+
convert_to_ogg(filepath, media_file)
391+
case _:
392+
raise NotImplemented
383393
response = FileResponse(open(filepath, "rb"))
384394
cleanup_form(form)
385395
return response

0 commit comments

Comments
 (0)