Ticket #7298: trac-7298-ogv.patch
File trac-7298-ogv.patch, 8.8 KB (added by , 13 years ago) |
---|
-
sage/misc/html.py
# HG changeset patch # User Wilfried Huss <huss@finanz.math.tugraz.at> # Date 1255722005 -7200 # Node ID c714be4e402bb2544f3614beca7fe88dffc79d26 # Parent 6b36a63b1833fc784289041a598c98094ce82534 Ogg Theora video support for animations diff -r 6b36a63b1833 -r c714be4e402b sage/misc/html.py
a b 267 267 column_tag = "<th>%s</th>" 268 268 269 269 from sage.plot.plot import Graphics 270 from sage.plot.animate import Animation 270 271 import types 271 272 if isinstance(row, types.GeneratorType): 272 273 row = list(row) … … 274 275 row = [row] 275 276 276 277 for column in xrange(len(row)): 277 if isinstance(row[column], Graphics):278 if isinstance(row[column], (Graphics, Animation)): 278 279 print column_tag % row[column].show(linkmode = True) 279 280 elif isinstance(row[column], str): 280 281 print column_tag % math_parse(row[column]) -
sage/plot/animate.py
diff -r 6b36a63b1833 -r c714be4e402b sage/plot/animate.py
a b 350 350 print "" 351 351 print "See www.imagemagick.org, for example." 352 352 353 def show(self, delay=20, iterations=0): 353 def ogv(self, delay=20, savefile=None, iterations=0, show_path=False): 354 r""" 355 Returns an Ogg Theora video of the graphics 356 objects in self. 357 358 This function will only work if the libtheora spkg is installed. 359 360 INPUT: 361 362 363 - ``delay`` - (default: 20) delay in hundredths of a 364 second between frames 365 366 - ``savefile`` - file that the Ogg Theora video gets saved 367 to 368 369 - ``iterations`` - integer (default: 0); number of 370 iterations of animation. If 0, loop forever. 371 372 - ``show_path`` - boolean (default: False); if True, 373 print the path to the saved file 374 375 376 If savefile is not specified: in notebook mode, display the 377 animation; otherwise, save it to a default file name. 378 379 EXAMPLES:: 380 381 sage: a = animate([sin(x + float(k)) for k in srange(0,2*pi,0.7)], 382 ... xmin=0, xmax=2*pi, figsize=[2,1]) 383 sage: a.ogv() # optional -- requires libtheora 384 sage: a.ogv(delay=35, iterations=3) # optional -- requires libtheora 385 sage: a.ogv(savefile='my_animation.ogv') # optional -- requires libtheora 386 sage: a.ogv(savefile='my_animation.ogv', show_path=True) # optional -- requires libtheora 387 Animation saved to .../my_animation.ogv. 388 389 .. note:: 390 391 If libtheora is not installed, you will get an error 392 message like this:: 393 394 Error: libtheora does not appear to be installed. Saving an 395 animation to a Ogg Theora file or displaying an animation 396 requires the libtheora spkg, so please install it and try again. 397 """ 398 if not savefile: 399 savefile = sage.misc.misc.graphics_filename(ext='ogv') 400 if not savefile.endswith('.ogv'): 401 savefile += '.ogv' 402 savefile = os.path.abspath(savefile) 403 d = self.png() 404 #cmd = 'cd "%s"; sage-native-execute ffmpeg2theora %%08d.png --inputfps %s -o "%s" 2> /dev/null'%(d, 100/delay, savefile) 405 cmd = 'cd "%s"; sage-native-execute png2theora -o "%s" -f %s %%08d.png 2> /dev/null'%(d, savefile, int(100/delay)) 406 from subprocess import check_call, CalledProcessError 407 try: 408 check_call(cmd, shell=True) 409 if show_path: 410 print "Animation saved to file %s." % savefile 411 except (CalledProcessError, OSError): 412 print "" 413 print "Error: libtheora does not appear to be installed. Saving an" 414 print "animation to a Ogg Theora file or displaying an animation requires the" 415 print "libtheora spkg, so please install it and try again." 416 417 418 def show(self, delay=20, iterations=0, format='gif', linkmode = False): 354 419 r""" 355 420 Show this animation. 356 421 … … 363 428 - ``iterations`` - integer (default: 0); number of 364 429 iterations of animation. If 0, loop forever. 365 430 431 - ``format`` - (default: 'gif') the output format. 432 Either 'gif' or 'ogv'. 366 433 367 434 .. note:: 368 435 … … 376 443 sage: a = animate([sin(x + float(k)) for k in srange(0,2*pi,0.7)], 377 444 ... xmin=0, xmax=2*pi, figsize=[2,1]) 378 445 sage: a.show() # optional -- requires convert command 446 447 sage: b = animate([sin(y*x^2)*cos(x/2) for y in srange(0,2,0.05)], xmin = -pi, xmax=pi, ymax = 1, ymin = -1) 448 sage: b.show(format = 'ogv') # optional -- requires libtheora 379 449 380 450 The preceding will loop the animation forever. If you want to show 381 451 only three iterations instead:: … … 401 471 See www.imagemagick.org, for example. 402 472 """ 403 473 if plot.DOCTEST_MODE: 404 self.gif(delay = delay, iterations = iterations) 474 if format == 'ogv': 475 self.ogv(delay = delay, iterations = iterations) 476 else: 477 self.gif(delay = delay, iterations = iterations) 478 405 479 return 406 480 407 481 if plot.EMBEDDED_MODE: 408 self.gif(delay = delay, iterations = iterations) 482 if format == 'ogv': 483 filename = sage.misc.misc.graphics_filename(ext='ogv') 484 self.ogv(delay = delay, savefile=filename, iterations = iterations) 485 video_tag = """<video autoplay controls> 486 <source src="cell://%s" type="video/ogg" /> 487 <a target="_new" href="cell://%s" class="file_link">ogv</a> 488 </video>""" % (filename, filename) 489 if linkmode == True: 490 return video_tag 491 else: 492 from sage.misc.html import html 493 html(video_tag) 494 else: 495 filename = sage.misc.misc.graphics_filename(ext='gif') 496 self.gif(delay = delay, savefile=filename, iterations = iterations) 497 gif_tag = """<img src="cell://%s"/>""" % filename 498 if linkmode == True: 499 return gif_tag 500 else: 501 from sage.misc.html import html 502 html(gif_tag) 409 503 else: 410 filename = sage.misc.misc.tmp_filename() + '.gif' 411 self.gif(delay=delay, savefile=filename, iterations=iterations) 504 if format == 'ogv': 505 filename = sage.misc.misc.tmp_filename() + '.ogv' 506 self.ogv(delay=delay, savefile=filename, iterations=iterations) 507 else: 508 filename = sage.misc.misc.tmp_filename() + '.gif' 509 self.gif(delay=delay, savefile=filename, iterations=iterations) 412 510 os.system('%s %s 2>/dev/null 1>/dev/null &'%( 413 511 sage.misc.viewer.browser(), filename)) 414 512 415 513 def save(self, filename=None, show_path=False): 416 514 """ 417 Save this animation into a gif or sobj file.515 Save this animation into a gif, ogv (Ogg Theora video) or sobj file. 418 516 419 517 INPUT: 420 518 … … 428 526 If filename is None, then in notebook mode, display the animation; 429 527 otherwise, save the animation to a gif file. If filename ends in 430 528 '.gif', save to a gif file. If filename ends in '.sobj', save to an 431 sobj file. 529 sobj file, and if it ends with '.ogv', save it to an Ogg Theora 530 video file. 432 531 433 532 In all other cases, print an error. 434 533 … … 440 539 sage: a.save('wave.gif') # optional 441 540 sage: a.save('wave.gif', show_path=True) # optional 442 541 Animation saved to file .../wave.gif. 542 sage: a.save('wave.ogv', show_path=True) # optional -- requires libtheora 543 Animation saved to file .../wave.ogv. 443 544 sage: a.save('wave0.sobj') # optional 444 545 sage: a.save('wave1.sobj', show_path=True) # optional 445 546 Animation saved to file wave1.sobj. … … 447 548 if filename is None or filename.endswith('.gif'): 448 549 self.gif(savefile=filename, show_path=show_path) 449 550 return 551 elif filename.endswith('.ogv'): 552 self.ogv(savefile=filename, show_path=show_path) 553 return 450 554 elif filename.endswith('.sobj'): 451 555 SageObject.save(self, filename) 452 556 if show_path: