Fix video mirroring issue (#2475)

* Fix video flip + test

* CHANGELOG

* Fix python 3.7 mock syntax

* Fix python 3.7 syntax

* Use .stem

* Lint
This commit is contained in:
Freddy Boulton 2022-10-18 11:07:03 -04:00 committed by GitHub
parent f79a76ca8f
commit dae17bb75a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 64 additions and 16 deletions

View File

@ -66,8 +66,8 @@ gr.Interface(iteration,
## Bug Fixes:
* Add loading status tracker UI to HTML and Markdown components. [@pngwn](https://github.com/pngwn) in [PR 2474](https://github.com/gradio-app/gradio/pull/2474)
* Fixed videos being mirrored in the front-end if source is not webcam by [@freddyaboulton](https://github.com/freddyaboulton) in [PR 2475](https://github.com/gradio-app/gradio/pull/2475)
## Documentation Changes:
No changes to highlight.

View File

@ -1640,25 +1640,26 @@ class Video(Changeable, Clearable, Playable, IOComponent, FileSerializable):
file_data, file_path=file_name
)
file_name = file.name
uploaded_format = file_name.split(".")[-1].lower()
file_name = Path(file.name)
uploaded_format = file_name.suffix.replace(".", "")
if self.format is not None and uploaded_format != self.format:
output_file_name = file_name[0 : file_name.rindex(".") + 1] + self.format
ff = FFmpeg(inputs={file_name: None}, outputs={output_file_name: None})
ff.run()
return output_file_name
elif self.source == "webcam" and self.mirror_webcam is True:
path = Path(file_name)
output_file_name = str(path.with_stem(f"{path.stem}_flip"))
modify_format = self.format is not None and uploaded_format != self.format
flip = self.source == "webcam" and self.mirror_webcam
if modify_format or flip:
format = f".{self.format if modify_format else uploaded_format}"
output_options = ["-vf", "hflip", "-c:a", "copy"] if flip else None
flip_suffix = "_flip" if flip else ""
output_file_name = str(
file_name.with_name(f"{file_name.stem}{flip_suffix}{format}")
)
ff = FFmpeg(
inputs={file_name: None},
outputs={output_file_name: ["-vf", "hflip", "-c:a", "copy"]},
inputs={str(file_name): None},
outputs={output_file_name: output_options},
)
ff.run()
return output_file_name
else:
return file_name
return str(file_name)
def generate_sample(self):
"""Generates a random video for testing the API."""

View File

@ -1234,7 +1234,9 @@ class TestVideo(unittest.TestCase):
x_video["is_example"] = True
self.assertIsNotNone(video_input.preprocess(x_video))
video_input = gr.Video(format="avi")
self.assertEqual(video_input.preprocess(x_video)[-3:], "avi")
output_video = video_input.preprocess(x_video)
self.assertEqual(output_video[-3:], "avi")
assert "flip" not in output_video
assert filecmp.cmp(
video_input.serialize(x_video["name"])["name"], x_video["name"]
@ -1291,6 +1293,45 @@ class TestVideo(unittest.TestCase):
)
assert processing_utils.video_is_playable(str(full_path_to_output))
@patch("gradio.components.FFmpeg")
def test_video_preprocessing_flips_video_for_webcam(self, mock_ffmpeg):
x_video = deepcopy(media_data.BASE64_VIDEO)
video_input = gr.Video(source="webcam")
_ = video_input.preprocess(x_video)
# Dict mapping filename to FFmpeg options
output_params = mock_ffmpeg.call_args_list[0][1]["outputs"]
assert "hflip" in list(output_params.values())[0]
assert "flip" in list(output_params.keys())[0]
mock_ffmpeg.reset_mock()
_ = gr.Video(source="webcam", mirror_webcam=False).preprocess(x_video)
mock_ffmpeg.assert_not_called()
mock_ffmpeg.reset_mock()
_ = gr.Video(source="upload", format="mp4").preprocess(x_video)
mock_ffmpeg.assert_not_called()
mock_ffmpeg.reset_mock()
output_file = gr.Video(
source="webcam", mirror_webcam=True, format="avi"
).preprocess(x_video)
output_params = mock_ffmpeg.call_args_list[0][1]["outputs"]
assert "hflip" in list(output_params.values())[0]
assert "flip" in list(output_params.keys())[0]
assert ".avi" in list(output_params.keys())[0]
assert ".avi" in output_file
mock_ffmpeg.reset_mock()
output_file = gr.Video(
source="webcam", mirror_webcam=False, format="avi"
).preprocess(x_video)
output_params = mock_ffmpeg.call_args_list[0][1]["outputs"]
assert list(output_params.values())[0] is None
assert "flip" not in list(output_params.keys())[0]
assert ".avi" in list(output_params.keys())[0]
assert ".avi" in output_file
class TestTimeseries(unittest.TestCase):
def test_component_functions(self):

View File

@ -70,7 +70,13 @@
<ModifyUpload on:clear={handle_clear} />
{#if playable()}
<!-- svelte-ignore a11y-media-has-caption -->
<Player src={value.data} on:play on:pause on:ended mirror={mirror_webcam} />
<Player
src={value.data}
on:play
on:pause
on:ended
mirror={mirror_webcam && source === "webcam"}
/>
{:else if value.size}
<div class="file-name text-4xl p-6 break-all">{value.name}</div>
<div class="file-size text-2xl p-2">