Merge pull request #985 from 3b1b/remove-livestream

Remove livestream
This commit is contained in:
Devin Neal 2020-04-17 00:08:17 -07:00 committed by GitHub
commit 1bb2e8c237
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 5 additions and 146 deletions

View file

@ -124,31 +124,9 @@ Documentation is in progress at [eulertour.com/docs](https://www.eulertour.com/d
### Walkthrough
Todd Zimmerman put together a [tutorial](https://talkingphysics.wordpress.com/2019/01/08/getting-started-animating-with-manim-and-python-3-7/) on getting started with manim, which has been updated to run on Python 3.7.
### Live Streaming
To live stream your animations, simply run manim with the `--livestream` option.
```sh
> python -m manim --livestream
Writing to media/videos/scene/scene/1080p30/LiveStreamTemp.mp4
Manim is now running in streaming mode. Stream animations by passing
them to manim.play(), e.g.
>>> c = Circle()
>>> manim.play(ShowCreation(c))
>>>
```
It is also possible to stream directly to Twitch. To do that simply pass
`--livestream` and `--to-twitch to manim` and specify the stream key with
`--with-key`. Then when you follow the above example the stream will directly
start on your Twitch channel (with no audio support).
## Contributing
Is always welcome. In particular, there is a dire need for tests and documentation.
## License
All files in the directory `from_3b1b`, which by and large generate the visuals for 3b1b videos, are copyright 3Blue1Brown.

View file

@ -3,5 +3,3 @@ import manimlib
if __name__ == "__main__":
manimlib.main()
else:
manimlib.stream_starter.start_livestream()

View file

@ -2,17 +2,10 @@
import manimlib.config
import manimlib.constants
import manimlib.extract_scene
import manimlib.stream_starter
def main():
args = manimlib.config.parse_cli()
if not args.livestream:
config = manimlib.config.get_configuration(args)
manimlib.constants.initialize_directories(config)
manimlib.extract_scene.main(config)
else:
manimlib.stream_starter.start_livestream(
to_twitch=args.to_twitch,
twitch_key=args.twitch_key,
)
config = manimlib.config.get_configuration(args)
manimlib.constants.initialize_directories(config)
manimlib.extract_scene.main(config)

View file

@ -129,35 +129,7 @@ def parse_cli():
"--tex_dir",
help="directory to write tex",
)
# For live streaming
module_location.add_argument(
"--livestream",
action="store_true",
help="Run in streaming mode",
)
parser.add_argument(
"--to-twitch",
action="store_true",
help="Stream to twitch",
)
parser.add_argument(
"--with-key",
dest="twitch_key",
help="Stream key for twitch",
)
args = parser.parse_args()
if args.file is None and not args.livestream:
parser.print_help()
sys.exit(2)
if args.to_twitch and not args.livestream:
print("You must run in streaming mode in order to stream to twitch")
sys.exit(2)
if args.to_twitch and args.twitch_key is None:
print("Specify the twitch stream key with --with-key")
sys.exit(2)
return args
return parser.parse_args()
except argparse.ArgumentError as err:
print(str(err))
sys.exit(2)

View file

@ -552,17 +552,6 @@ class Scene(Container):
self.update_frame(ignore_skipping=True)
self.get_image().show()
# TODO, this doesn't belong in Scene, but should be
# part of some more specialized subclass optimized
# for livestreaming
def tex(self, latex):
eq = TextMobject(latex)
anims = []
anims.append(Write(eq))
for mobject in self.mobjects:
anims.append(ApplyMethod(mobject.shift, 2 * UP))
self.play(*anims)
class EndSceneEarlyException(Exception):
pass

View file

@ -28,9 +28,6 @@ class SceneFileWriter(object):
"save_last_frame": False,
"movie_file_extension": ".mp4",
"gif_file_extension": ".gif",
"livestreaming": False,
"to_twitch": False,
"twitch_key": None,
# Previous output_file_name
# TODO, address this in extract_scene et. al.
"file_name": None,
@ -171,15 +168,10 @@ class SceneFileWriter(object):
def begin_animation(self, allow_write=False):
if self.write_to_movie and allow_write:
self.open_movie_pipe()
if self.livestreaming:
self.stream_lock = False
def end_animation(self, allow_write=False):
if self.write_to_movie and allow_write:
self.close_movie_pipe()
if self.livestreaming:
self.stream_lock = True
thread.start_new_thread(self.idle_stream, ())
def write_frame(self, frame):
if self.write_to_movie:
@ -247,22 +239,12 @@ class SceneFileWriter(object):
'-vcodec', 'libx264',
'-pix_fmt', 'yuv420p',
]
if self.livestreaming:
if self.to_twitch:
command += ['-f', 'flv']
command += ['rtmp://live.twitch.tv/app/' + self.twitch_key]
else:
command += ['-f', 'mpegts']
command += [STREAMING_PROTOCOL + '://' + STREAMING_IP + ':' + STREAMING_PORT]
else:
command += [temp_file_path]
command += [temp_file_path]
self.writing_process = subprocess.Popen(command, stdin=subprocess.PIPE)
def close_movie_pipe(self):
self.writing_process.stdin.close()
self.writing_process.wait()
if self.livestreaming:
return True
shutil.move(
self.temp_partial_movie_file_path,
self.partial_movie_file_path,

View file

@ -1,53 +0,0 @@
from time import sleep
import code
import os
import readline
import subprocess
from manimlib.scene.scene import Scene
import manimlib.constants
def start_livestream(to_twitch=False, twitch_key=None):
class Manim():
def __new__(cls):
kwargs = {
"scene_name": manimlib.constants.LIVE_STREAM_NAME,
"open_video_upon_completion": False,
"show_file_in_finder": False,
# By default, write to file
"write_to_movie": True,
"show_last_frame": False,
"save_pngs": False,
# If -t is passed in (for transparent), this will be RGBA
"saved_image_mode": "RGB",
"movie_file_extension": ".mp4",
"quiet": True,
"ignore_waits": False,
"write_all": False,
"name": manimlib.constants.LIVE_STREAM_NAME,
"start_at_animation_number": 0,
"end_at_animation_number": None,
"skip_animations": False,
"camera_config": manimlib.constants.HIGH_QUALITY_CAMERA_CONFIG,
"livestreaming": True,
"to_twitch": to_twitch,
"twitch_key": twitch_key,
}
return Scene(**kwargs)
if not to_twitch:
FNULL = open(os.devnull, 'w')
subprocess.Popen(
[manimlib.constants.STREAMING_CLIENT, manimlib.constants.STREAMING_URL],
stdout=FNULL,
stderr=FNULL)
sleep(3)
variables = globals().copy()
variables.update(locals())
shell = code.InteractiveConsole(variables)
shell.push("manim = Manim()")
shell.push("from manimlib.imports import *")
shell.interact(banner=manimlib.constants.STREAMING_CONSOLE_BANNER)