#!/usr/bin/env python3 # # vidi-timeline - generate GStreamer Editing Services timelines from midi # # Copyright (C) 2016 Antonio Ospite # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import os import sys import mido import vidi # TODO: turn these into command line options ADD_REST_BACKGROUND = True ADD_TITLE = True TITLE_TEXT = None TITLE_DURATION = 5 TITLE_CREDITS = "Created with vidi-timeline\nhttps://git.ao2.it/vidi-player.git" CANVAS_SIZE = (640, 480) def timeline_from_midi(midi_file, canvas_size, video_font_path): timeline = vidi.Timeline(canvas_size) if ADD_TITLE: title = TITLE_TEXT if not title: title = os.path.splitext(os.path.basename(midi_file.filename))[0] title += "\n\n" title += TITLE_CREDITS timeline.add_title_clip(title, 0, TITLE_DURATION) elapsed_time = start_time = TITLE_DURATION else: elapsed_time = start_time = 0 for msg in midi_file: elapsed_time += msg.time if vidi.is_note_on(msg) and msg.channel == 0: start_time = elapsed_time elif vidi.is_note_off(msg) and msg.channel == 0: note = vidi.MidiNote(msg.note) duration = elapsed_time - start_time print("Note name: %3s start_time: %f duration: %f" % (note.name, start_time, duration)) video_sample_path = "%s/sample_%s.webm" % (video_font_path, note.name) timeline.add_clip(video_sample_path, start_time, duration) if ADD_REST_BACKGROUND: rest_sample_path = "%s/sample_rest.png" % video_font_path timeline.add_layer_clip(rest_sample_path, 0, elapsed_time) return timeline def usage(): print("usage: %s []" % os.path.basename(sys.argv[0])) def main(): if len(sys.argv) > 1 and sys.argv[1] in ["-h", "--help"]: usage() return 0 if len(sys.argv) < 3: usage() return 1 if not os.path.isdir(sys.argv[2]): sys.stderr.write("The second argument must be the path of the videofont directory\n") usage() return 1 if len(sys.argv) > 3 and os.path.exists(sys.argv[3]): sys.stderr.write("File '%s' exists, exiting!\n" % sys.argv[3]) return 1 midi_file = mido.MidiFile(sys.argv[1]) overlapping_notes = vidi.check_overlapping_notes(midi_file) if overlapping_notes: sys.stderr.write("Sorry, supporting only midi file with no overlapping notes on channel 0\n") return 1 video_font_path = os.path.realpath(sys.argv[2]) timeline = timeline_from_midi(midi_file, CANVAS_SIZE, video_font_path) if len(sys.argv) > 3: timeline.save(sys.argv[3]) else: try: timeline.play() except KeyboardInterrupt: timeline.stop() return 1 if __name__ == "__main__": sys.exit(main())