source: src/media_conv/conversion.py @ 4698

Last change on this file since 4698 was 4698, checked in by Sander.Maijers@mpi.nl, 10 years ago

Horizontal showcase WebMAUS:
media_conv component

Documentation: https://trac.clarin.eu/media_conv

As deployed on: http://infra.clarin.eu/app/media_conv

File size: 5.2 KB
Line 
1# -*- coding: utf-8 -*-
2__author__ = 'sanmai'
3
4import subprocess
5import os
6import tempfile
7import pprint
8import logging
9
10logger = logging.getLogger('waitress')
11
12
13def get_full_ffmpeg_command(ffmpeg_command, input_mime_type, output_mime_type, output_media_file_path):
14    full_ffmpeg_command = None
15
16    if input_mime_type == "audio/x-wav" and output_mime_type == "audio/mp4":
17        full_ffmpeg_command = [ffmpeg_command,
18                               "-i", "pipe:0",
19                               "-c:a", "libfdk_aac",
20                               "-b:a", "128k",
21                               "-nostdin", "-y",
22                               output_media_file_path]
23
24    if full_ffmpeg_command is not None:
25        logger.debug("Full ffmpeg command: " + " ".join(full_ffmpeg_command))
26
27        return full_ffmpeg_command
28    else:
29        raise NotImplementedError()
30
31
32def convert(input_media_data,
33            input_mime_type,
34            output_mime_type,
35            temp_directory_path,
36            ffmpeg_command):
37    try:
38        output_media_file_fd, output_media_file_path = tempfile.mkstemp(dir=temp_directory_path,
39                                                                        suffix=".m4a")
40        os.close(output_media_file_fd)
41
42        try:
43            full_ffmpeg_command = get_full_ffmpeg_command(ffmpeg_command,
44                                                          input_mime_type,
45                                                          output_mime_type,
46                                                          output_media_file_path)
47
48            process = subprocess.Popen(full_ffmpeg_command,
49                                       stdin=subprocess.PIPE,
50                                       stdout=subprocess.DEVNULL,
51                                       stderr=subprocess.DEVNULL,
52                                       shell=False,
53                                       close_fds=True,
54                                       universal_newlines=False)
55        except OSError as e:
56            logger.error("ffmpeg could not be launched. " + pprint.pprint(e))
57            raise
58        else:
59            try:
60                process.stdin.write(input_media_data)
61                process.stdin.flush()
62                process.stdin.close()
63                process.wait(timeout=180)
64
65            except subprocess.TimeoutExpired as e:
66                process.kill()
67                logger.error("ffmpeg process timed out. " + pprint.pprint(e))
68                raise
69            else:
70                try:
71                    with open(output_media_file_path,
72                              'rb') as output_media_file:
73                        output_media_file_data = output_media_file.read()
74
75                        try:
76                            if output_media_file_data is None:
77                                raise ChildProcessError()
78                        except ChildProcessError as e:
79                            logger.error("Output media file at '{0}' is empty. "
80                                             .format(output_media_file_path) + pprint.pprint(e))
81                            raise
82                        else:
83                            try:
84                                os.remove(output_media_file_path)
85                            except OSError as e:
86                                logger.error("Output media file at '{0}' could not be deleted after ffmpeg process. "
87                                                 .format(output_media_file_path) + pprint.pprint(e))
88                                raise
89                            else:
90                                logger.debug("Successful conversion from '{0}' to '{1}'. "
91                                    .format(input_mime_type, output_mime_type))
92                                return output_media_file_data
93                except OSError as e:
94                    logger.error("Output media file at '{0}' could not be read after ffmpeg process. "
95                                     .format(output_media_file_path) + pprint.pprint(e))
96                    raise
97    except Exception as e:
98        logger.error("Output media file could not be created. " + pprint.pprint(e))
99        raise
100
101
102class Converter(object):
103    def __init__(self,
104                 caching,
105                 temp_directory_path,
106                 ffmpeg_command):
107
108        self.caching = caching
109        self.temp_directory_path = temp_directory_path
110        self.ffmpeg_command = ffmpeg_command
111
112        if self.caching:
113            import media_conv.cache
114
115    def convert_media_file(self,
116                           input_media_data,
117                           input_mime_type,
118                           output_mime_type):
119        if self.caching:
120            logger.info("Caching is enabled. ")
121            raise NotImplementedError()
122        else:
123            output_media_data = convert(input_media_data=input_media_data,
124                                        input_mime_type=input_mime_type,
125                                        output_mime_type=output_mime_type,
126                                        temp_directory_path=self.temp_directory_path,
127                                        ffmpeg_command=self.ffmpeg_command)
128
129            return output_media_data
Note: See TracBrowser for help on using the repository browser.