mirror of
https://github.com/gradio-app/gradio.git
synced 2025-03-07 11:46:51 +08:00
Merge branch 'master' into feature/tab_title
This commit is contained in:
commit
4ea2664ff6
@ -3,7 +3,7 @@ import gradio as gr
|
||||
def video_flip(video):
|
||||
return video
|
||||
|
||||
iface = gr.Interface(video_flip, "video", "playable_video")
|
||||
iface = gr.Interface(video_flip, gr.inputs.Video(source="webcam"), "playable_video")
|
||||
|
||||
if __name__ == "__main__":
|
||||
iface.launch()
|
||||
|
@ -3,9 +3,9 @@
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
|
||||
<title>{{ config['title'] or 'Gradio' }}</title>
|
||||
<meta property="og:url" content="https://gradio.app/" />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:image" content="{{ config['thumbnail'] or '' }}" />
|
||||
|
@ -2,7 +2,6 @@ import React from "react";
|
||||
import BaseComponent from "../base_component";
|
||||
import { FileComponentExample } from "../component_example";
|
||||
import { isPlayable } from "../../utils";
|
||||
import edit_icon from "../../static/img/edit.svg";
|
||||
import clear_icon from "../../static/img/clear.svg";
|
||||
|
||||
class VideoInput extends BaseComponent {
|
||||
@ -10,10 +9,15 @@ class VideoInput extends BaseComponent {
|
||||
super(props);
|
||||
this.handleChange = this.handleChange.bind(this);
|
||||
this.uploader = React.createRef();
|
||||
this.videoRecorder = React.createRef();
|
||||
this.openFileUpload = this.openFileUpload.bind(this);
|
||||
this.load_preview_from_files = this.load_preview_from_files.bind(this);
|
||||
this.load_preview_from_upload = this.load_preview_from_upload.bind(this);
|
||||
this.load_preview_from_drop = this.load_preview_from_drop.bind(this);
|
||||
this.camera_stream = null;
|
||||
this.state = {
|
||||
recording: false,
|
||||
};
|
||||
}
|
||||
handleChange(evt) {
|
||||
this.props.handleChange(evt.target.value);
|
||||
@ -21,6 +25,36 @@ class VideoInput extends BaseComponent {
|
||||
openFileUpload() {
|
||||
this.uploader.current.click();
|
||||
}
|
||||
record = async () => {
|
||||
if (this.state.recording) {
|
||||
this.media_recorder.stop();
|
||||
let video_blob = new Blob(this.blobs_recorded, { type: 'video/webm' });
|
||||
var ReaderObj = new FileReader();
|
||||
ReaderObj.onload = (function(e) {
|
||||
this.props.handleChange({
|
||||
name: "sample.webm",
|
||||
data: e.target.result,
|
||||
is_example: false
|
||||
});
|
||||
}).bind(this);
|
||||
|
||||
ReaderObj.readAsDataURL(video_blob);
|
||||
|
||||
this.setState({ recording: false });
|
||||
} else {
|
||||
this.blobs_recorded = [];
|
||||
this.camera_stream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true });
|
||||
this.videoRecorder.current.srcObject = this.camera_stream;
|
||||
this.videoRecorder.current.volume = 0;
|
||||
this.media_recorder = new MediaRecorder(this.camera_stream, { mimeType: 'video/webm' });
|
||||
this.media_recorder.addEventListener('dataavailable', (function (e) {
|
||||
this.blobs_recorded.push(e.data);
|
||||
}).bind(this));
|
||||
this.media_recorder.start(200);
|
||||
this.videoRecorder.current.play();
|
||||
this.setState({ recording: true });
|
||||
}
|
||||
}
|
||||
render() {
|
||||
let no_action = (evt) => {
|
||||
evt.preventDefault();
|
||||
@ -50,7 +84,7 @@ class VideoInput extends BaseComponent {
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
} else if (this.props.source == "upload") {
|
||||
return (
|
||||
<div
|
||||
className="input_video"
|
||||
@ -81,6 +115,18 @@ class VideoInput extends BaseComponent {
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
} else if (this.props.source == "webcam") {
|
||||
return (
|
||||
<div className="input_video">
|
||||
<video ref={this.videoRecorder} class="video_recorder" autoplay></video>
|
||||
<div class="record_holder">
|
||||
<div class="record_message">
|
||||
{this.state.recording ? <>Stop Recording</> : <>Click to Record</>}
|
||||
</div>
|
||||
<button class="record" onClick={this.record}></button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
load_preview_from_drop(evt) {
|
||||
|
@ -439,6 +439,18 @@
|
||||
}
|
||||
.input_video {
|
||||
@apply w-full h-80 relative;
|
||||
.video_recorder {
|
||||
@apply w-full h-full bg-black;
|
||||
}
|
||||
.record_holder {
|
||||
@apply absolute left-1/2 bottom-4 -translate-x-1/2 -translate-y-1/2 text-center;
|
||||
}
|
||||
.record_message {
|
||||
@apply text-white font-bold mb-4;
|
||||
}
|
||||
.record {
|
||||
@apply w-12 h-12 rounded-full bg-red-500 hover:bg-red-600 border-4 border-red-600;
|
||||
}
|
||||
.upload_zone {
|
||||
@apply border-gray-300 text-gray-400 dark:border-gray-500 border-8 border-dashed w-full h-full flex justify-center items-center text-3xl text-center cursor-pointer leading-10;
|
||||
}
|
||||
|
@ -388,6 +388,18 @@ html {
|
||||
}
|
||||
.input_video {
|
||||
@apply w-full h-48;
|
||||
.video_recorder {
|
||||
@apply w-full h-full bg-black;
|
||||
}
|
||||
.record_holder {
|
||||
@apply absolute left-1/2 bottom-4 -translate-x-1/2 -translate-y-1/2 text-center;
|
||||
}
|
||||
.record_message {
|
||||
@apply text-white font-bold mb-4;
|
||||
}
|
||||
.record {
|
||||
@apply w-12 h-12 rounded-full bg-red-500 hover:bg-red-600 border-4 border-red-600;
|
||||
}
|
||||
.upload_zone {
|
||||
@apply bg-gray-200 hover:bg-gray-100 dark:bg-gray-500 dark:hover:bg-gray-400 text-gray-600 dark:text-gray-50 transition w-full h-full flex justify-center items-center text-xl text-center cursor-pointer leading-10;
|
||||
}
|
||||
|
@ -378,6 +378,18 @@
|
||||
}
|
||||
.input_video {
|
||||
@apply w-full h-80 relative;
|
||||
.video_recorder {
|
||||
@apply w-full h-full bg-black;
|
||||
}
|
||||
.record_holder {
|
||||
@apply absolute left-1/2 bottom-4 -translate-x-1/2 -translate-y-1/2 text-center;
|
||||
}
|
||||
.record_message {
|
||||
@apply text-white font-bold mb-4;
|
||||
}
|
||||
.record {
|
||||
@apply w-12 h-12 rounded-full bg-red-500 hover:bg-red-600 border-4 border-red-600;
|
||||
}
|
||||
.upload_zone {
|
||||
@apply border-8 border-gray-300 border-dashed w-full h-full flex justify-center items-center text-3xl text-gray-400 dark:border-gray-500 dark:text-gray-50 text-center cursor-pointer leading-10;
|
||||
}
|
||||
|
@ -391,6 +391,18 @@
|
||||
}
|
||||
.input_video {
|
||||
@apply w-full h-80;
|
||||
.video_recorder {
|
||||
@apply w-full h-full bg-black;
|
||||
}
|
||||
.record_holder {
|
||||
@apply absolute left-1/2 bottom-4 -translate-x-1/2 -translate-y-1/2 text-center;
|
||||
}
|
||||
.record_message {
|
||||
@apply text-white font-bold mb-4;
|
||||
}
|
||||
.record {
|
||||
@apply w-12 h-12 rounded-full bg-red-500 hover:bg-red-600 border-4 border-red-600;
|
||||
}
|
||||
.upload_zone {
|
||||
@apply border-red-300 text-red-400 dark:border-none dark:text-gray-50 border-8 border-dashed w-full h-full flex justify-center items-center text-3xl text-center cursor-pointer leading-10;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
Metadata-Version: 1.0
|
||||
Name: gradio
|
||||
Version: 2.4.6
|
||||
Version: 2.4.7b0
|
||||
Summary: Python library for easily interacting with trained machine learning models
|
||||
Home-page: https://github.com/gradio-app/gradio-UI
|
||||
Author: Abubakar Abid
|
||||
|
@ -877,14 +877,16 @@ class Video(InputComponent):
|
||||
Demos: video_flip.py
|
||||
"""
|
||||
|
||||
def __init__(self, type=None, label=None, optional=False):
|
||||
def __init__(self, type=None, source="upload", label=None, optional=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
|
||||
self.optional = optional
|
||||
super().__init__(label)
|
||||
|
||||
@ -896,6 +898,7 @@ class Video(InputComponent):
|
||||
|
||||
def get_template_context(self):
|
||||
return {
|
||||
"source": self.source,
|
||||
"optional": self.optional,
|
||||
**super().get_template_context()
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"files": {
|
||||
"main.css": "/static/css/main.ad1e2368.css",
|
||||
"main.css": "/static/css/main.062d1a9b.css",
|
||||
"main.js": "/static/bundle.js",
|
||||
"index.html": "/index.html",
|
||||
"static/media/arrow-left.e497f657.svg": "/static/media/arrow-left.e497f657.svg",
|
||||
@ -12,7 +12,7 @@
|
||||
},
|
||||
"entrypoints": [
|
||||
"static/bundle.css",
|
||||
"static/css/main.ad1e2368.css",
|
||||
"static/css/main.062d1a9b.css",
|
||||
"static/bundle.js"
|
||||
]
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
<!doctype html><html lang="en" style="height:100%"><head><meta charset="utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no"><meta property="og:url" content="https://gradio.app/"/><meta property="og:type" content="website"/><meta property="og:image" content="{{ config['thumbnail'] or '' }}"/><meta property="og:title" content="{{ config['title'] or '' }}"/><meta property="og:description" content="{{ config['description'] or '' }}"/><meta name="twitter:card" content="summary_large_image"><meta name="twitter:creator" content="@teamGradio"><meta name="twitter:title" content="{{ config['title'] or '' }}"><meta name="twitter:description" content="{{ config['description'] or '' }}"><meta name="twitter:image" content="{{ config['thumbnail'] or '' }}"><script async src="https://www.googletagmanager.com/gtag/js?id=UA-156449732-1"></script><script>window.dataLayer = window.dataLayer || [];
|
||||
<!doctype html><html lang="en" style="height:100%"><head><meta charset="utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no"><title>{{ config['title'] or 'Gradio' }}</title><meta property="og:url" content="https://gradio.app/"/><meta property="og:type" content="website"/><meta property="og:image" content="{{ config['thumbnail'] or '' }}"/><meta property="og:title" content="{{ config['title'] or '' }}"/><meta property="og:description" content="{{ config['description'] or '' }}"/><meta name="twitter:card" content="summary_large_image"><meta name="twitter:creator" content="@teamGradio"><meta name="twitter:title" content="{{ config['title'] or '' }}"><meta name="twitter:description" content="{{ config['description'] or '' }}"><meta name="twitter:image" content="{{ config['thumbnail'] or '' }}"><script async src="https://www.googletagmanager.com/gtag/js?id=UA-156449732-1"></script><script>window.dataLayer = window.dataLayer || [];
|
||||
function gtag() {
|
||||
dataLayer.push(arguments);
|
||||
}
|
||||
@ -8,4 +8,4 @@
|
||||
window.config = {{ config|tojson }};
|
||||
} catch (e) {
|
||||
window.config = {};
|
||||
}</script><script src="https://cdnjs.cloudflare.com/ajax/libs/iframe-resizer/4.3.1/iframeResizer.contentWindow.min.js"></script><title>{{ config['tab_title'] or 'Gradio' }}</title><link href="static/bundle.css" rel="stylesheet"><link href="static/css/main.ad1e2368.css" rel="stylesheet"></head><body style="height:100%"><div id="root" style="height:100%"></div><script src="static/bundle.js"></script></body></html>
|
||||
}</script><script src="https://cdnjs.cloudflare.com/ajax/libs/iframe-resizer/4.3.1/iframeResizer.contentWindow.min.js"></script><title>{{ config['tab_title'] or 'Gradio' }}</title><link href="static/bundle.css" rel="stylesheet"><link href="static/css/main.062d1a9b.css" rel="stylesheet"></head><body style="height:100%"><div id="root" style="height:100%"></div><script src="static/bundle.js"></script></body></html>
|
@ -1 +1 @@
|
||||
2.4.6
|
||||
2.4.7b
|
||||
|
2
setup.py
2
setup.py
@ -5,7 +5,7 @@ except ImportError:
|
||||
|
||||
setup(
|
||||
name='gradio',
|
||||
version='2.4.6',
|
||||
version='2.4.7b',
|
||||
include_package_data=True,
|
||||
description='Python library for easily interacting with trained machine learning models',
|
||||
author='Abubakar Abid',
|
||||
|
@ -518,6 +518,7 @@ class TestVideo(unittest.TestCase):
|
||||
self.assertIsInstance(video_input.generate_sample(), dict)
|
||||
video_input = gr.inputs.Video(label="Upload Your Video")
|
||||
self.assertEqual(video_input.get_template_context(), {
|
||||
'source': 'upload',
|
||||
'optional': False,
|
||||
'name': 'video',
|
||||
'label': 'Upload Your Video'
|
||||
|
Loading…
Reference in New Issue
Block a user