Reputation:
I have a Flask app running on Heroku and what I am trying to do is use FFmpeg to re-encode a video to x265. For that, I have the following route
@app.route('/x265', methods=['POST'])
def rotax265():
up_file = request.files['file'].stream
in_file = tempfile.TemporaryFile()
in_file.write(up_file.read())
in_file.seek(0)
out_file = tempfile.TemporaryFile()
conv = VideoConverter(in_file, out_file)
conv.x265()
out_file.seek(0)
return out_file.read()
It uses a VideoConverter
class that I created:
class VideoConverter(object):
def __init__(self, in_file, out_file):
self.input = in_file
self.output = out_file
def x265(self, read_chunk_size=-1):
args = (
ffmpeg
.input('pipe:', format='matroska')
.output('pipe:', vcodec='libx265', format='matroska')
.get_args()
)
p = subprocess.Popen(
['ffmpeg'] + args, stdin=self.input, stdout=self.output)
p.wait()
This class is using ffmpeg-python
and subprocess
modules.
I am using pipe both in input and output so that I don't use storage space and avoid receiving R-14 errors (memory quota exceeded).
This works as expected when running locally, but when I try to run the script on the Heroku server, it still returns R-14 errors.
Is there any way I can avoid getting those errors?
Upvotes: 1
Views: 765
Reputation: 136968
I am using pipe both in input and output so that I don't use storage space and avoid receiving R-14 errors (memory quota exceeded).
Storage (disk) and memory (RAM) are different things. This error is about memory.
Your pipes may prevent you from writing to disk, but they don't do anything to reduce memory usage. In fact, they may increase memory usage—the data must exist somewhere, and if it can't be written to disk it needs to stay in memory.
If you're getting memory issues on Heroku you only have two options:
Video conversion generally takes a lot of memory, and I'm not aware of any good ways of reducing that aside from working with very short video clips. This leaves you with one real option: invest in bigger dynos.
Upvotes: 1