-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #56 from nicholas-fr/master
Audio mezzanine JSON metadata and long duration mezzanine audio creation
- Loading branch information
Showing
6 changed files
with
310 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
#!/usr/bin/env python | ||
|
||
import argparse | ||
import json | ||
import os | ||
import sys | ||
|
||
from pathlib import Path | ||
|
||
WAVE_MEZZ_RELEASES_URL = 'https://dash-large-files.akamaized.net/WAVE/Mezzanine/releases/' | ||
FILE_WAV = '.wav' | ||
FILE_JSON = '.json' | ||
|
||
adb_json_filename = 'audio_mezzanine_database.json' | ||
adb_json = {'audio':{}} | ||
|
||
# Basic argument handling | ||
parser = argparse.ArgumentParser(description="WAVE Audio Mezzanine JSON DB Creator.") | ||
parser.add_argument('path', help="Path to folder containing audio mezzanine files.") | ||
|
||
args = parser.parse_args() | ||
|
||
if os.path.isdir(str(Path(args.path))): | ||
mezz_path = Path(args.path) | ||
else: | ||
sys.exit('Invalid path to audio mezzanine files: ' + str(args.path)) | ||
|
||
print('Searching for all audio mezzanine files...') | ||
wav_files = os.listdir(str(mezz_path)) | ||
for wav in wav_files: | ||
if wav.startswith('PN') and wav.endswith(FILE_WAV): | ||
print('Audio mezzanine found: ' + wav) | ||
wav_json_file_path = Path(str(mezz_path) + '/' + wav[:-4]+FILE_JSON) | ||
if os.path.isfile(str(wav_json_file_path)): | ||
wav_json_file = open(wav_json_file_path) | ||
wav_json = (json.load(wav_json_file)) | ||
wav_json_file.close() | ||
print('Corresponding metadata found: ' + str(wav_json_file_path)) | ||
mezz_version = wav_json['Mezzanine']['version'] | ||
print('Mezzanine release version: ' + str(mezz_version)) | ||
else: | ||
sys.exit('JSON metadata missing for ' + wav + '. Ensure JSON metadata files are in the same folder as their correponding audio mezzanine files.' ) | ||
|
||
adb_json['audio'][wav[:-4]] = {'path': WAVE_MEZZ_RELEASES_URL+str(mezz_version)+'/'+wav, 'json_path': WAVE_MEZZ_RELEASES_URL+str(mezz_version)+'/'+wav[:-4]+FILE_JSON} | ||
|
||
# Save metadata to JSON file | ||
adb_json_filepath = str(mezz_path) + '/' + adb_json_filename | ||
adb_json_file = open(adb_json_filepath, "w") | ||
json.dump(adb_json, adb_json_file, indent=4) | ||
adb_json_file.write('\n') | ||
adb_json_file.close() | ||
|
||
print("Audio mezzanine JSON database saved: "+str(adb_json_filepath)) | ||
print() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
#!/usr/bin/env python | ||
|
||
""" | ||
This program takes an existing WAVE video mezzanine file (MP4) and an existing WAVE audio mezzanine file (WAV). | ||
It loops the audio mezzanine and replaces the video mezzanine file's audio track with the looped audio. | ||
""" | ||
|
||
import argparse | ||
import json | ||
import os | ||
import subprocess | ||
import sys | ||
|
||
from pathlib import Path | ||
|
||
# Basic argument handling | ||
parser = argparse.ArgumentParser(description="WAVE Mezzanine Audio: looping white noise.") | ||
parser.add_argument('input1', help="Source mezzanine file.") | ||
parser.add_argument('input2', help="Source audio file to loop.") | ||
|
||
args = parser.parse_args() | ||
|
||
# Check that source files are present | ||
if not os.path.isfile(args.input1): | ||
sys.exit("Source file \""+args.input1+"\" does not exist.") | ||
if not os.path.isfile(args.input2): | ||
sys.exit("Source file \""+args.input2+"\" does not exist.") | ||
|
||
mezzanine = Path(args.input1) | ||
second_audio = Path(args.input2) | ||
mezzanine_out = Path(str(mezzanine.stem)+'_'+str(second_audio.stem)+str(mezzanine.suffix)) | ||
|
||
print("Creating new mezzanine file using video from "+str(mezzanine)+" and (looped) audio from "+str(second_audio)) | ||
|
||
# Detect video mezzanine duration | ||
source_videoproperties = subprocess.check_output( | ||
['ffprobe', '-i', str(mezzanine), '-show_streams', '-select_streams', 'v', '-loglevel', '0', '-print_format', 'json']) | ||
source_videoproperties_json = json.loads(source_videoproperties) | ||
duration = int(source_videoproperties_json['streams'][0]['duration'].split('.')[0]) | ||
|
||
# Create audio track with the same duration as the video mezzanine by looping audio mezzanine | ||
subprocess.run(['ffmpeg', | ||
'-stream_loop', '-1', '-i', str(second_audio), '-t', str(duration), | ||
'-y', | ||
str(second_audio.stem)+'_looped.wav']) | ||
|
||
# Encode and mux new audio track with video mezzanine | ||
# ffmpeg -i <mezzanine_file> -i second_audio_looped.wav -map 0:v -map 1:a -c:v copy -c:a aac -b:a 320k -ac 2 <mezzanine_file_with_new_audio> | ||
subprocess.run(['ffmpeg', | ||
'-i', str(mezzanine), | ||
'-i', str(second_audio.stem)+'_looped.wav', | ||
'-map', '0:v', | ||
'-map', '1:a', | ||
'-c:v','copy', | ||
'-c:a','aac', | ||
'-b:a', '320k', '-ac', '2', | ||
'-y', | ||
str(mezzanine_out)]) | ||
|
||
os.remove(str(second_audio.stem)+'_looped.wav') | ||
print("Done") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
© Consumer Technology Association (CTA)®, licensed under Creative Commons Attribution 4.0 International (CC BY 4.0) (https://creativecommons.org/licenses/by/4.0/) / annotated, encoded and compressed from original. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
{ | ||
"audio": { | ||
"PN01": { | ||
"path": "https://dash-large-files.akamaized.net/WAVE/Mezzanine/releases/4/PN01.wav", | ||
"json_path": "https://dash-large-files.akamaized.net/WAVE/Mezzanine/releases/4/PN01.json" | ||
}, | ||
"PN02": { | ||
"path": "https://dash-large-files.akamaized.net/WAVE/Mezzanine/releases/4/PN02.wav", | ||
"json_path": "https://dash-large-files.akamaized.net/WAVE/Mezzanine/releases/4/PN02.json" | ||
}, | ||
"PN03": { | ||
"path": "https://dash-large-files.akamaized.net/WAVE/Mezzanine/releases/4/PN03.wav", | ||
"json_path": "https://dash-large-files.akamaized.net/WAVE/Mezzanine/releases/4/PN03.json" | ||
}, | ||
"PN04": { | ||
"path": "https://dash-large-files.akamaized.net/WAVE/Mezzanine/releases/4/PN04.wav", | ||
"json_path": "https://dash-large-files.akamaized.net/WAVE/Mezzanine/releases/4/PN04.json" | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters