mirror of
https://github.com/gradio-app/gradio.git
synced 2024-12-21 02:19:59 +08:00
Blocks-Components
- move video component
This commit is contained in:
parent
921d0b03cf
commit
cf32e0097c
@ -11,6 +11,7 @@ from typing import Any, Dict, List, Optional, Tuple
|
||||
|
||||
import numpy as np
|
||||
import PIL
|
||||
from ffmpy import FFmpeg
|
||||
|
||||
from gradio import processing_utils, test_data
|
||||
from gradio.blocks import Block
|
||||
@ -507,7 +508,7 @@ class Slider(Component):
|
||||
if step is None:
|
||||
difference = maximum - minimum
|
||||
power = math.floor(math.log10(difference) - 2)
|
||||
step = 10**power
|
||||
step = 10 ** power
|
||||
self.step = step
|
||||
self.default = minimum if default is None else default
|
||||
self.test_input = self.default
|
||||
@ -931,6 +932,7 @@ class Image(Component):
|
||||
):
|
||||
"""
|
||||
Parameters:
|
||||
default(str): IGNORED
|
||||
shape (Tuple[int, int]): (width, height) shape to crop and resize image to; if None, matches input image size.
|
||||
image_mode (str): "RGB" if color, or "L" if black and white.
|
||||
invert_colors (bool): whether to invert the image as a preprocessing step.
|
||||
@ -1210,3 +1212,122 @@ class Image(Component):
|
||||
|
||||
def restore_flagged(self, dir, data, encryption_key):
|
||||
return self.restore_flagged_file(dir, data, encryption_key)["data"]
|
||||
|
||||
|
||||
class Video(Component):
|
||||
"""
|
||||
Component creates a video file upload that is converted to a file path.
|
||||
|
||||
Input type: filepath
|
||||
Output type: filepath
|
||||
Demos: video_flip
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
default="",
|
||||
*,
|
||||
type: Optional[str] = None,
|
||||
source: str = "upload",
|
||||
label: Optional[str] = None,
|
||||
optional: bool = False,
|
||||
):
|
||||
"""
|
||||
Parameters:
|
||||
default (str): IGNORED
|
||||
type (str): Type of video format to be returned by component, such as 'avi' or 'mp4'. Use 'mp4' to ensure browser playability. If set to None, video will keep uploaded format.
|
||||
source (str): Source of video. "upload" creates a box where user can drop an video file, "webcam" allows user to record a video from their webcam.
|
||||
label (str): component name in interface.
|
||||
optional (bool): If True, the interface can be submitted with no uploaded video, in which case the input value is None.
|
||||
"""
|
||||
self.type = type
|
||||
self.source = source
|
||||
super().__init__(label=label, optional=optional)
|
||||
|
||||
@classmethod
|
||||
def get_shortcut_implementations(cls):
|
||||
return {
|
||||
"video": {},
|
||||
"playable_video": {"type": "mp4"},
|
||||
}
|
||||
|
||||
def get_template_context(self):
|
||||
return {
|
||||
"source": self.source,
|
||||
"optional": self.optional,
|
||||
**super().get_template_context(),
|
||||
}
|
||||
|
||||
def preprocess_example(self, x):
|
||||
return {"name": x, "data": None, "is_example": True}
|
||||
|
||||
def preprocess(self, x: Dict[str, str] | None) -> str | None:
|
||||
"""
|
||||
Parameters:
|
||||
x (Dict[name: str, data: str]): JSON object with filename as 'name' property and base64 data as 'data' property
|
||||
Returns:
|
||||
(str): file path to video
|
||||
"""
|
||||
if x is None:
|
||||
return x
|
||||
file_name, file_data, is_example = (
|
||||
x["name"],
|
||||
x["data"],
|
||||
x.get("is_example", False),
|
||||
)
|
||||
if is_example:
|
||||
file = processing_utils.create_tmp_copy_of_file(file_name)
|
||||
else:
|
||||
file = processing_utils.decode_base64_to_file(
|
||||
file_data, file_path=file_name
|
||||
)
|
||||
file_name = file.name
|
||||
uploaded_format = file_name.split(".")[-1].lower()
|
||||
if self.type is not None and uploaded_format != self.type:
|
||||
output_file_name = file_name[0: file_name.rindex(".") + 1] + self.type
|
||||
ff = FFmpeg(inputs={file_name: None}, outputs={output_file_name: None})
|
||||
ff.run()
|
||||
return output_file_name
|
||||
else:
|
||||
return file_name
|
||||
|
||||
def serialize(self, x, called_directly):
|
||||
raise NotImplementedError()
|
||||
|
||||
def save_flagged(self, dir, label, data, encryption_key):
|
||||
"""
|
||||
Returns: (str) path to video file
|
||||
"""
|
||||
return self.save_flagged_file(
|
||||
dir, label, None if data is None else data["data"], encryption_key
|
||||
)
|
||||
# TODO: Might need to converge these two
|
||||
# Output save_flagged:
|
||||
# return self.save_flagged_file(dir, label, data["data"], encryption_key)
|
||||
|
||||
def generate_sample(self):
|
||||
return test_data.BASE64_VIDEO
|
||||
|
||||
def postprocess(self, y):
|
||||
"""
|
||||
Parameters:
|
||||
y (str): path to video
|
||||
Returns:
|
||||
(str): base64 url data
|
||||
"""
|
||||
returned_format = y.split(".")[-1].lower()
|
||||
if self.type is not None and returned_format != self.type:
|
||||
output_file_name = y[0: y.rindex(".") + 1] + self.type
|
||||
ff = FFmpeg(inputs={y: None}, outputs={output_file_name: None})
|
||||
ff.run()
|
||||
y = output_file_name
|
||||
return {
|
||||
"name": os.path.basename(y),
|
||||
"data": processing_utils.encode_file_to_base64(y),
|
||||
}
|
||||
|
||||
def deserialize(self, x):
|
||||
return processing_utils.decode_base64_to_file(x).name
|
||||
|
||||
def restore_flagged(self, dir, data, encryption_key):
|
||||
return self.restore_flagged_file(dir, data, encryption_key)
|
||||
|
119
gradio/inputs.py
119
gradio/inputs.py
@ -278,6 +278,10 @@ class Image(Image):
|
||||
label (str): component name in interface.
|
||||
optional (bool): If True, the interface can be submitted with no uploaded image, in which case the input value is None.
|
||||
"""
|
||||
warnings.warn(
|
||||
"Usage of gradio.inputs is deprecated, and will not be supported in the future, please import your component from gradio.components",
|
||||
DeprecationWarning,
|
||||
)
|
||||
super().__init__(
|
||||
shape=shape,
|
||||
image_mode=image_mode,
|
||||
@ -290,6 +294,35 @@ class Image(Image):
|
||||
)
|
||||
|
||||
|
||||
class Video(Component):
|
||||
"""
|
||||
Component creates a video file upload that is converted to a file path.
|
||||
|
||||
Input type: filepath
|
||||
Demos: video_flip
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
type: Optional[str] = None,
|
||||
source: str = "upload",
|
||||
label: Optional[str] = None,
|
||||
optional: bool = False,
|
||||
):
|
||||
"""
|
||||
Parameters:
|
||||
type (str): Type of video format to be returned by component, such as 'avi' or 'mp4'. If set to None, video will keep uploaded format.
|
||||
source (str): Source of video. "upload" creates a box where user can drop an video file, "webcam" allows user to record a video from their webcam.
|
||||
label (str): component name in interface.
|
||||
optional (bool): If True, the interface can be submitted with no uploaded video, in which case the input value is None.
|
||||
"""
|
||||
warnings.warn(
|
||||
"Usage of gradio.inputs is deprecated, and will not be supported in the future, please import your components from gradio.components",
|
||||
DeprecationWarning,
|
||||
)
|
||||
super().__init__(type=type, source=source, label=label, optional=optional)
|
||||
|
||||
|
||||
class InputComponent(Component):
|
||||
"""
|
||||
Input Component. All input components subclass this.
|
||||
@ -373,92 +406,6 @@ class InputComponent(Component):
|
||||
}
|
||||
|
||||
|
||||
class Video(InputComponent):
|
||||
"""
|
||||
Component creates a video file upload that is converted to a file path.
|
||||
Input type: filepath
|
||||
Demos: video_flip
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
type: Optional[str] = None,
|
||||
source: str = "upload",
|
||||
label: Optional[str] = None,
|
||||
optional: bool = False,
|
||||
):
|
||||
"""
|
||||
Parameters:
|
||||
type (str): Type of video format to be returned by component, such as 'avi' or 'mp4'. If set to None, video will keep uploaded format.
|
||||
source (str): Source of video. "upload" creates a box where user can drop an video file, "webcam" allows user to record a video from their webcam.
|
||||
label (str): component name in interface.
|
||||
optional (bool): If True, the interface can be submitted with no uploaded video, in which case the input value is None.
|
||||
"""
|
||||
self.type = type
|
||||
self.source = source
|
||||
super().__init__(label, optional=optional)
|
||||
|
||||
@classmethod
|
||||
def get_shortcut_implementations(cls):
|
||||
return {
|
||||
"video": {},
|
||||
}
|
||||
|
||||
def get_template_context(self):
|
||||
return {
|
||||
"source": self.source,
|
||||
"optional": self.optional,
|
||||
**super().get_template_context(),
|
||||
}
|
||||
|
||||
def preprocess_example(self, x):
|
||||
return {"name": x, "data": None, "is_example": True}
|
||||
|
||||
def preprocess(self, x: Dict[str, str] | None) -> str | None:
|
||||
"""
|
||||
Parameters:
|
||||
x (Dict[name: str, data: str]): JSON object with filename as 'name' property and base64 data as 'data' property
|
||||
Returns:
|
||||
(str): file path to video
|
||||
"""
|
||||
if x is None:
|
||||
return x
|
||||
file_name, file_data, is_example = (
|
||||
x["name"],
|
||||
x["data"],
|
||||
x.get("is_example", False),
|
||||
)
|
||||
if is_example:
|
||||
file = processing_utils.create_tmp_copy_of_file(file_name)
|
||||
else:
|
||||
file = processing_utils.decode_base64_to_file(
|
||||
file_data, file_path=file_name
|
||||
)
|
||||
file_name = file.name
|
||||
uploaded_format = file_name.split(".")[-1].lower()
|
||||
if self.type is not None and uploaded_format != self.type:
|
||||
output_file_name = file_name[0 : file_name.rindex(".") + 1] + self.type
|
||||
ff = FFmpeg(inputs={file_name: None}, outputs={output_file_name: None})
|
||||
ff.run()
|
||||
return output_file_name
|
||||
else:
|
||||
return file_name
|
||||
|
||||
def serialize(self, x, called_directly):
|
||||
raise NotImplementedError()
|
||||
|
||||
def save_flagged(self, dir, label, data, encryption_key):
|
||||
"""
|
||||
Returns: (str) path to video file
|
||||
"""
|
||||
return self.save_flagged_file(
|
||||
dir, label, None if data is None else data["data"], encryption_key
|
||||
)
|
||||
|
||||
def generate_sample(self):
|
||||
return test_data.BASE64_VIDEO
|
||||
|
||||
|
||||
class Audio(InputComponent):
|
||||
"""
|
||||
Component accepts audio input files.
|
||||
|
@ -21,7 +21,7 @@ import PIL
|
||||
from ffmpy import FFmpeg
|
||||
|
||||
from gradio import processing_utils
|
||||
from gradio.components import Component, Image, Textbox
|
||||
from gradio.components import Component, Image, Textbox, Video
|
||||
|
||||
if TYPE_CHECKING: # Only import for type checking (is False at runtime).
|
||||
from gradio import Interface
|
||||
@ -65,6 +65,26 @@ class Image(Image):
|
||||
super().__init__(label=label, type=type, plot=plot)
|
||||
|
||||
|
||||
class Video(Video):
|
||||
"""
|
||||
Used for video output.
|
||||
Output type: filepath
|
||||
Demos: video_flip
|
||||
"""
|
||||
|
||||
def __init__(self, type: Optional[str] = None, label: Optional[str] = None):
|
||||
"""
|
||||
Parameters:
|
||||
type (str): Type of video format to be passed to component, such as 'avi' or 'mp4'. Use 'mp4' to ensure browser playability. If set to None, video will keep returned format.
|
||||
label (str): component name in interface.
|
||||
"""
|
||||
warnings.warn(
|
||||
"Usage of gradio.outputs is deprecated, and will not be supported in the future, please import your components from gradio.components",
|
||||
DeprecationWarning,
|
||||
)
|
||||
super().__init__(label=label, type=type)
|
||||
|
||||
|
||||
class OutputComponent(Component):
|
||||
"""
|
||||
Output Component. All output components subclass this.
|
||||
@ -191,54 +211,6 @@ class Label(OutputComponent):
|
||||
return data
|
||||
|
||||
|
||||
class Video(OutputComponent):
|
||||
"""
|
||||
Used for video output.
|
||||
Output type: filepath
|
||||
Demos: video_flip
|
||||
"""
|
||||
|
||||
def __init__(self, type: Optional[str] = None, label: Optional[str] = None):
|
||||
"""
|
||||
Parameters:
|
||||
type (str): Type of video format to be passed to component, such as 'avi' or 'mp4'. Use 'mp4' to ensure browser playability. If set to None, video will keep returned format.
|
||||
label (str): component name in interface.
|
||||
"""
|
||||
self.type = type
|
||||
super().__init__(label)
|
||||
|
||||
@classmethod
|
||||
def get_shortcut_implementations(cls):
|
||||
return {"video": {}, "playable_video": {"type": "mp4"}}
|
||||
|
||||
def postprocess(self, y):
|
||||
"""
|
||||
Parameters:
|
||||
y (str): path to video
|
||||
Returns:
|
||||
(str): base64 url data
|
||||
"""
|
||||
returned_format = y.split(".")[-1].lower()
|
||||
if self.type is not None and returned_format != self.type:
|
||||
output_file_name = y[0 : y.rindex(".") + 1] + self.type
|
||||
ff = FFmpeg(inputs={y: None}, outputs={output_file_name: None})
|
||||
ff.run()
|
||||
y = output_file_name
|
||||
return {
|
||||
"name": os.path.basename(y),
|
||||
"data": processing_utils.encode_file_to_base64(y),
|
||||
}
|
||||
|
||||
def deserialize(self, x):
|
||||
return processing_utils.decode_base64_to_file(x).name
|
||||
|
||||
def save_flagged(self, dir, label, data, encryption_key):
|
||||
return self.save_flagged_file(dir, label, data["data"], encryption_key)
|
||||
|
||||
def restore_flagged(self, dir, data, encryption_key):
|
||||
return self.restore_flagged_file(dir, data, encryption_key)
|
||||
|
||||
|
||||
class KeyValues(OutputComponent):
|
||||
"""
|
||||
Component displays a table representing values for multiple fields.
|
||||
|
Loading…
Reference in New Issue
Block a user