Spaces:
Runtime error
Runtime error
Upload app.py
Browse files
app.py
CHANGED
@@ -25,7 +25,7 @@ def get_demo_call(video_name):
|
|
25 |
elif video_name.startswith("ball"):
|
26 |
ump_out = "Ball"
|
27 |
else:
|
28 |
-
ump_out =
|
29 |
return ump_out
|
30 |
|
31 |
def call_pitch(pitch):
|
@@ -52,7 +52,10 @@ def call_pitch(pitch):
|
|
52 |
while time.time() - start < (video_length-5)/15: #wait until the video is done to return the call and go 2 frames early to seem speedy
|
53 |
time.sleep(0.1)
|
54 |
|
55 |
-
|
|
|
|
|
|
|
56 |
|
57 |
def generate_random_pitch():
|
58 |
random_number = random.randint(1,2645342) #random number in our range to select a random pitch
|
@@ -72,28 +75,65 @@ def generate_random_pitch():
|
|
72 |
random_pitch = download_pitch(video_link,ump_out)
|
73 |
|
74 |
return random_pitch
|
75 |
-
|
|
|
|
|
76 |
#download and process the video link using yt-dlp and ffmpeg
|
77 |
-
|
78 |
-
|
79 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
80 |
|
81 |
|
82 |
demo_files = os.listdir("demo_files/")
|
83 |
demo_files = [os.path.join("demo_files/", file) for file in demo_files if file.endswith(".mp4")]
|
84 |
with gr.Blocks(title="Picklebot") as demo:
|
85 |
-
with gr.
|
86 |
-
with gr.
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
97 |
|
|
|
|
|
|
|
|
|
|
|
98 |
if __name__ == "__main__":
|
99 |
demo.launch()
|
|
|
25 |
elif video_name.startswith("ball"):
|
26 |
ump_out = "Ball"
|
27 |
else:
|
28 |
+
ump_out = None
|
29 |
return ump_out
|
30 |
|
31 |
def call_pitch(pitch):
|
|
|
52 |
while time.time() - start < (video_length-5)/15: #wait until the video is done to return the call and go 2 frames early to seem speedy
|
53 |
time.sleep(0.1)
|
54 |
|
55 |
+
if ump_out is not None:
|
56 |
+
return final_call,ump_out
|
57 |
+
else:
|
58 |
+
return final_call
|
59 |
|
60 |
def generate_random_pitch():
|
61 |
random_number = random.randint(1,2645342) #random number in our range to select a random pitch
|
|
|
75 |
random_pitch = download_pitch(video_link,ump_out)
|
76 |
|
77 |
return random_pitch
|
78 |
+
|
79 |
+
|
80 |
+
def download_pitch(video_link,ump_out=None):
|
81 |
#download and process the video link using yt-dlp and ffmpeg
|
82 |
+
if ump_out is not None:
|
83 |
+
video_out = f"demo_files/downloaded_videos/{ump_out}_demo_video.mp4"
|
84 |
+
os.system(f"yt-dlp -q --no-warnings --force-overwrites -f mp4 {video_link} -o '{video_out}'")
|
85 |
+
os.system(f'ffmpeg -y -nostats -loglevel 0 -i {video_out} -vf "crop=700:700:in_w/2-350:in_h/2-350,scale=224:224" -r 15 -c:v libx264 -crf 23 -c:a aac -an -strict experimental {video_out}_cropped_video.mp4')
|
86 |
+
else:
|
87 |
+
video_out = f"demo_files/downloaded_videos/own_demo_video.mp4"
|
88 |
+
os.system(f"yt-dlp -q --no-warnings --force-overwrites -f mp4 {video_link} -o '{video_out}'")
|
89 |
+
os.system(f'ffmpeg -y -nostats -loglevel 0 -i {video_out} -vf "crop=700:700:in_w/2-350:in_h/2-350,scale=224:224" -r 15 -c:v libx264 -crf 23 -c:a aac -strict experimental {video_out}_cropped_video.mp4')
|
90 |
+
return f"{video_out}_cropped_video.mp4"
|
91 |
|
92 |
|
93 |
demo_files = os.listdir("demo_files/")
|
94 |
demo_files = [os.path.join("demo_files/", file) for file in demo_files if file.endswith(".mp4")]
|
95 |
with gr.Blocks(title="Picklebot") as demo:
|
96 |
+
with gr.Tab("Picklebot"):
|
97 |
+
with gr.Row():
|
98 |
+
with gr.Column(scale=3):
|
99 |
+
inp = gr.Video(interactive=False, label="Pitch Video")
|
100 |
+
with gr.Column(scale=2):
|
101 |
+
ump_out = gr.Label(label="Umpire's Original Call")
|
102 |
+
pb_out = gr.Label(label="Picklebot's Call")
|
103 |
+
random_button = gr.Button("🔀 Load a Random Pitch")
|
104 |
+
random_button.click(fn=generate_random_pitch,outputs=[inp])
|
105 |
+
inp.play(fn=call_pitch,inputs=inp,outputs=[pb_out,ump_out])
|
106 |
+
gr.ClearButton([inp,pb_out,ump_out])
|
107 |
+
gr.Examples(demo_files,inputs=inp,outputs=[inp])
|
108 |
+
with gr.Tab("Use Your Own Video!"):
|
109 |
+
with gr.Row():
|
110 |
+
gr.Markdown(value=
|
111 |
+
"""
|
112 |
+
# Here\'s how to use your own video:
|
113 |
+
1. Navigate to [Baseball Savant's statcast search](https://baseballsavant.mlb.com/statcast_search)
|
114 |
+
2. Choose the situation and pitch you want (just keep in mind that the network was only trained on called balls and called strikes)
|
115 |
+
3. Click on the pitcher or batter's name to get to list of pitches
|
116 |
+
4. Right click on the camera icon to the right, and copy the link
|
117 |
+
5. Paste the video url in below, and press go to download the pitch
|
118 |
+
6. Watch the video and see what Picklebot thinks!
|
119 |
+
""")
|
120 |
+
with gr.Row():
|
121 |
+
with gr.Column(scale=3):
|
122 |
+
vid_inp = gr.Video(interactive=False, label="Pitch Video")
|
123 |
+
with gr.Column(scale=2):
|
124 |
+
#make a textbox to take in the user's video link
|
125 |
+
input_txt = gr.Textbox(placeholder="Paste your video link here",label="Video Link")
|
126 |
+
input_txt.submit(fn=download_pitch,inputs=input_txt,outputs=vid_inp)
|
127 |
+
submit_button = gr.Button("Go!")
|
128 |
+
submit_button.click(fn=download_pitch,inputs=input_txt,outputs=vid_inp)
|
129 |
+
pb_out = gr.Label(label="Picklebot's Call")
|
130 |
+
vid_inp.play(fn=call_pitch,inputs=vid_inp,outputs=pb_out)
|
131 |
+
gr.ClearButton([vid_inp,pb_out,input_txt])
|
132 |
|
133 |
+
with gr.Tab("About"):
|
134 |
+
gr.Markdown(value=
|
135 |
+
"""Picklebot is a 3D Convolutional Neural Network that classifies baseball pitches as balls or strikes.
|
136 |
+
It was trained on the [Picklebot-50K Dataset](https://huggingface.co/datasets/hbfreed/Picklebot-50K),
|
137 |
+
comprised of over fifty thousand pitches to achieve ~80% accuracy.""")
|
138 |
if __name__ == "__main__":
|
139 |
demo.launch()
|