Browse Source

tag generated audio files; see #23

boyska 10 years ago
parent
commit
7022d05f6b
4 changed files with 55 additions and 7 deletions
  1. 10 0
      RELEASE.md
  2. 4 0
      server/default_config.py
  3. 30 3
      server/forge.py
  4. 11 4
      server/server.py

+ 10 - 0
RELEASE.md

@@ -0,0 +1,10 @@
+Version 1.2:
+
+* Added `TAG_EXTRA` option
+  suggested keys for TAG_EXTRA are `CREATOR`, `PUBLISHER`, `CONTACT`
+* Added `TAG_LICENSE_URI` option
+  It should be a link to a license. For example: 
+  http://creativecommons.org/publicdomain/zero/1.0/
+  Note that if you don't set TAG_LICENSE_URI, there will be no RIGHTS-DATE tag
+
+vim: set ft=markdown:

+ 4 - 0
server/default_config.py

@@ -20,3 +20,7 @@ FORGE_TIMEOUT = 20
 FORGE_MAX_DURATION = 3600*5
 FFMPEG_OPTIONS = ['-loglevel', 'warning', '-n']
 FFMPEG_PATH = 'ffmpeg'
+# tag:value pairs
+TAG_EXTRA = {}
+# LICENSE URI is special because date need to be added
+TAG_LICENSE_URI = None

+ 30 - 3
server/forge.py

@@ -49,7 +49,7 @@ def get_files_and_intervals(start, end, rounder=round_timefile):
         start = begin + timedelta(hours=1)
 
 
-def mp3_join(named_intervals, target):
+def mp3_join(named_intervals):
     '''
     Note that these are NOT the intervals returned by get_files_and_intervals,
     as they do not supply a filename, but only a datetime.
@@ -83,7 +83,6 @@ def mp3_join(named_intervals, target):
         startskip = 0
     if endskip is not None:
         cmdline += ['-t', str(len(files)*3600 - (startskip + endskip))]
-    cmdline += [target]
     return cmdline
 
 
@@ -97,7 +96,35 @@ def create_mp3(start, end, outfile, options={}, **kwargs):
         if not os.path.exists(path):
             raise OSError("file '%s' does not exist; recording system broken?"
                           % path)
-    p = Popen(mp3_join(intervals, outfile) + get_config()['FFMPEG_OPTIONS'])
+
+    # metadata date/time formatted according to
+    # https://wiki.xiph.org/VorbisComment#Date_and_time
+    metadata = {}
+    if outfile.endswith('.mp3'):
+        metadata['TRDC'] = start.replace(microsecond=0).isoformat()
+        metadata['RECORDINGTIME'] = metadata['TRDC']
+        metadata['ENCODINGTIME'] = datetime.now().replace(
+            microsecond=0).isoformat()
+    else:
+        metadata['DATE'] = start.replace(microsecond=0).isoformat()
+    metadata['ENCODER'] = 'https://github.com/boyska/techrec'
+    if 'title' in options:
+        metadata['TITLE'] = options['title']
+    if options.get('license_uri', None) is not None:
+        metadata['RIGHTS-DATE'] = start.strftime('%Y-%m')
+        metadata['RIGHTS-URI'] = options['license_uri']
+    if 'extra_tags' in options:
+        metadata.update(options['extra_tags'])
+    metadata_list = []
+    for tag, value in metadata.items():
+        if '=' in tag:
+            logging.error('Received a tag with "=" inside, skipping')
+            continue
+        metadata_list.append('-metadata')
+        metadata_list.append('%s=%s' % (tag, value))
+
+    p = Popen(mp3_join(intervals) + metadata_list +
+              get_config()['FFMPEG_OPTIONS'] + [outfile])
     if get_config()['FORGE_TIMEOUT'] == 0:
         p.wait()
     else:

+ 11 - 4
server/server.py

@@ -169,7 +169,13 @@ class RecAPI(Bottle):
             create_mp3,
             start=rec.starttime,
             end=rec.endtime,
-            outfile=os.path.join(get_config()['AUDIO_OUTPUT'], rec.filename))
+            outfile=os.path.join(get_config()['AUDIO_OUTPUT'], rec.filename),
+            options={
+                'title': rec.name,
+                'license_uri': get_config()['TAG_LICENSE_URI'],
+                'extra_tags': get_config()['TAG_EXTRA']
+            }
+        )
         logger.debug("SUBMITTED: %d" % job_id)
         return self.rec_msg("Aggiornamento completato!",
                             job_id=job_id,
@@ -271,7 +277,7 @@ class RecServer:
         self.db = RecDB(get_config()['DB_URI'])
 
     def _route(self):
-        ## Static part of the site
+        # Static part of the site
         self._app.route('/output/<filepath:path>',
                         callback=lambda filepath:
                         static_file(filepath,
@@ -329,8 +335,9 @@ class DebugAPI(Bottle):
     /big/<int:exponent> : returns a 2**n -1 byte content
     '''
 
+
 class PasteLoggingServer(bottle.PasteServer):
-    def run(self, handler): # pragma: no cover
+    def run(self, handler):  # pragma: no cover
         from paste import httpserver
         from paste.translogger import TransLogger
         handler = TransLogger(handler, **self.options['translogger_opts'])
@@ -352,7 +359,7 @@ def main_cmd(*args):
     if server == 'pastelog':
         from paste.translogger import TransLogger
         get_config()['WSGI_SERVER_OPTIONS']['translogger_opts'] = \
-                get_config()['TRANSLOGGER_OPTS']
+            get_config()['TRANSLOGGER_OPTS']
 
     c._app.run(server=server,
                host=get_config()['HOST'],