From 9cb5d8efe236967bfa4a1d9e4e20c3ba41ac9d7f Mon Sep 17 00:00:00 2001 From: Mathias Koehler Date: Fri, 16 Mar 2012 23:07:50 +0100 Subject: [PATCH] Change stdout reading and add a test --- ffmpegwrapper/ffmpeg.py | 14 +++++++++----- test.py | 33 +++++++++++++++------------------ 2 files changed, 24 insertions(+), 23 deletions(-) diff --git a/ffmpegwrapper/ffmpeg.py b/ffmpegwrapper/ffmpeg.py index 2c7cd60..f6cd7f0 100644 --- a/ffmpegwrapper/ffmpeg.py +++ b/ffmpegwrapper/ffmpeg.py @@ -72,13 +72,16 @@ class FFmpegProcess(object): """Read the output from the command bytewise. On every newline the line is put to the queue.""" line = '' - while self.process.poll() is None: + running = self.process.poll() is None + + while running: chunk = out.read(1).decode('utf-8') if chunk == '': + running = self.process.poll() is None continue line += chunk if chunk in ('\n', '\r'): - queue.put(line) + queue.put(line, timeout=0.4) line = '' out.close() @@ -104,15 +107,16 @@ class FFmpegProcess(object): :param keepends: keep the newlines at the end. Default=False """ - while self.process.poll() is None: + running = self.process.poll() is None + while running or self.queue.qsize(): try: - line = self.queue.get(timeout=0.1) + line = self.queue.get(timeout=0.05) if keepends: yield line else: yield line.rstrip('\r\n') except Empty: - pass + running = self.process.poll() is None def __getattr__(self, name): if self.process: diff --git a/test.py b/test.py index 16b3c50..047dbd0 100644 --- a/test.py +++ b/test.py @@ -12,25 +12,21 @@ from ffmpegwrapper.options import Option class FFmpegTestCase(unittest.TestCase): def setUp(self): - patcher = patch('ffmpegwrapper.ffmpeg.Popen') - popen = patcher.start() + self.patcher = patch('ffmpegwrapper.ffmpeg.Popen') + popen = self.patcher.start() self.instance = popen.return_value - poll_values = [None] * 80 - def poll(*args): - if len(poll_values) < 1: - return 0 - poll_values.pop(0) - self.instance.poll.side_effect = poll - read_value = list('this is a line\nthis too\n') - def read(*args): - if len(read_value) > 0: - return read_value.pop(0).encode('utf-8') - return ''.encode('utf-8') - self.instance.stdout.read.side_effect = read + poll = lambda: None if read_value else 0 - self.addCleanup(patcher.stop) + def read(*args): + try: + return read_value.pop(0).encode('utf-8') + except IndexError: + return ''.encode('utf-8') + + self.instance.poll.side_effect = poll + self.instance.stdout.read.side_effect = read def test_input_interface(self): input = Input('/old') @@ -83,9 +79,10 @@ class FFmpegTestCase(unittest.TestCase): with ffmpeg as process: result = list(process.readlines()) - self.assertEqual(result[0], 'this is a line') - self.assertEqual(result[1], 'this too') - self.assertEqual(len(result), 2) + self.assertEqual(result, ['this is a line', 'this too']) + + def tearDown(self): + self.patcher.stop() class VideoFilterTestCase(unittest.TestCase):