-
Notifications
You must be signed in to change notification settings - Fork 385
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Issue #841: Native AMP video playlists.
Create a custom shortcode handler for video playlists. Use <amp-video> and <amp-state>, on Weston't suggestion. This still doesn't support audio playlists.
- Loading branch information
Ryan Kienstra
committed
Feb 11, 2018
1 parent
1ab37c6
commit 00a3f08
Showing
4 changed files
with
205 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
<?php | ||
/** | ||
* Class AMP_Playlist_Embed_Handler | ||
* | ||
* @package AMP | ||
* @since 0.7 | ||
*/ | ||
|
||
/** | ||
* Class AMP_Playlist_Embed_Handler | ||
*/ | ||
class AMP_Playlist_Embed_Handler extends AMP_Base_Embed_Handler { | ||
|
||
/** | ||
* The ID of the individual playlist. | ||
* | ||
* @var int | ||
*/ | ||
public static $playlist_id = 0; | ||
|
||
/** | ||
* Registers the playlist shortcode. | ||
*/ | ||
public function register_embed() { | ||
add_shortcode( 'playlist', array( $this, 'shortcode' ) ); | ||
} | ||
|
||
/** | ||
* Unregisters the playlist shortcode. | ||
* | ||
* @return void. | ||
*/ | ||
public function unregister_embed() { | ||
remove_shortcode( 'playlist' ); | ||
} | ||
|
||
/** | ||
* Outputs an AMP-compliant playlist shortcode. | ||
* | ||
* Uses the JSON that wp_playlist_shortcode() produces. | ||
* But outputs an <amp-video>, and an <amp-state> to change the current video. | ||
* | ||
* @global content_width. | ||
* @param array $attr The playlist attributes. | ||
* @return string Playlist shortcode markup. | ||
*/ | ||
public function shortcode( $attr ) { | ||
global $content_width; | ||
|
||
$markup = wp_playlist_shortcode( $attr ); | ||
preg_match( '/(?s)\<script [^>]* class="wp-playlist-script"\>[^<]*?(.*).*?\<\/script\>/', $markup, $matches ); | ||
if ( empty( $matches[1] ) ) { | ||
return; | ||
} | ||
$data = json_decode( $matches[1], true ); | ||
if ( ! isset( $data['tracks'], $data['tracks'][0]['src'] ) ) { | ||
return; | ||
} | ||
|
||
$amp_state = array( | ||
'currentVideo' => '0', | ||
); | ||
foreach ( $data['tracks'] as $index => $track ) { | ||
$amp_state[ $index ] = array( | ||
'videoUrl' => isset( $track['src'] ) ? $track['src'] : '', | ||
'thumb' => isset( $track['thumb']['src'] ) ? $track['thumb']['src'] : '', | ||
); | ||
} | ||
$playlist = 'playlist' . self::$playlist_id++; | ||
$dimensions = isset( $data['tracks'][0]['dimensions']['resized'] ) ? $data['tracks'][0]['dimensions']['resized'] : null; | ||
$width = isset( $dimensions['width'] ) ? $dimensions['width'] : $content_width; | ||
$height = isset( $dimensions['height'] ) ? $dimensions['height'] : null; | ||
|
||
ob_start(); | ||
?> | ||
<div class="wp-playlist wp-video-playlist wp-playlist-light"> | ||
<amp-state id="<?php echo esc_attr( $playlist ); ?>"> | ||
<script type="application/json"> | ||
<?php echo wp_unslash( wp_json_encode( $amp_state ) ); // WPCS: XSS ok. ?> | ||
</script> | ||
</amp-state> | ||
<amp-video id="amp-video" src="<?php echo esc_url( $data['tracks'][0]['src'] ); ?>" [src]="<?php echo esc_attr( $playlist ); ?>[<?php echo esc_attr( $playlist ); ?>.currentVideo].videoUrl" width="<?php echo esc_attr( $width ); ?>" height="<?php echo isset( $height ) ? esc_attr( $height ) : ''; ?>" controls></amp-video> | ||
<div class="wp-playlist-tracks"> | ||
<?php | ||
$i = 1; | ||
foreach ( $data['tracks'] as $index => $track ) { | ||
if ( ! empty( $track['caption'] ) ) { | ||
$title = $track['caption']; | ||
} elseif ( ! empty( $track['title'] ) ) { | ||
$title = $track['title']; | ||
} | ||
?> | ||
<div class="wp-playlist-item"> | ||
<a class="wp-playlist-caption" on="tap:AMP.setState({<?php echo esc_attr( $playlist ); ?>: {currentVideo: <?php echo esc_attr( $index ); ?>}})"> | ||
<?php echo esc_html( $i . '.' ); ?> <span class="wp-playlist-item-title"><?php echo isset( $title ) ? esc_html( $title ) : ''; ?></span> | ||
</a> | ||
<?php if ( isset( $track['meta']['length_formatted'] ) ) : ?> | ||
<div class="wp-playlist-item-length"><?php echo esc_html( $track['meta']['length_formatted'] ); ?></div> | ||
<?php endif; ?> | ||
</div> | ||
<?php | ||
$i++; | ||
} | ||
?> | ||
</div> | ||
</div> | ||
<?php | ||
return ob_get_clean(); // WPCS: XSS ok. | ||
} | ||
|
||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
<?php | ||
/** | ||
* Tests for AMP_Playlist_Embed_Handler. | ||
* | ||
* @package AMP | ||
* @since 0.7 | ||
*/ | ||
|
||
/** | ||
* Tests for AMP_Playlist_Embed_Handler. | ||
* | ||
* @covers AMP_Playlist_Embed_Handler | ||
*/ | ||
class Test_AMP_Playlist_Embed_Handler extends WP_UnitTestCase { | ||
|
||
/** | ||
* Instance of the tested class. | ||
* | ||
* @var AMP_Playlist_Embed_Handler. | ||
*/ | ||
public $instance; | ||
|
||
/** | ||
* Set up test. | ||
*/ | ||
public function setUp() { | ||
parent::setUp(); | ||
$this->instance = new AMP_Playlist_Embed_Handler(); | ||
} | ||
|
||
/** | ||
* Tear down test. | ||
*/ | ||
public function tearDown() { | ||
wp_dequeue_style( 'wp-mediaelement' ); | ||
} | ||
|
||
/** | ||
* Test register_embed. | ||
* | ||
* @covers AMP_Playlist_Embed_Handler::register_embed() | ||
*/ | ||
public function test_register_embed() { | ||
global $shortcode_tags; | ||
$shortcode = 'playlist'; | ||
$this->assertFalse( isset( $shortcode_tags[ $shortcode ] ) ); | ||
$this->instance->register_embed(); | ||
$this->assertEquals( 'AMP_Playlist_Embed_Handler', get_class( $shortcode_tags[ $shortcode ][0] ) ); | ||
$this->assertEquals( 'shortcode', $shortcode_tags[ $shortcode ][1] ); | ||
$this->instance->unregister_embed(); | ||
} | ||
|
||
/** | ||
* Test unregister_embed. | ||
* | ||
* @covers AMP_Playlist_Embed_Handler::unregister_embed() | ||
*/ | ||
public function test_unregister_embed() { | ||
global $shortcode_tags; | ||
$shortcode = 'playlist'; | ||
$this->instance->unregister_embed(); | ||
$this->assertFalse( isset( $shortcode_tags[ $shortcode ] ) ); | ||
} | ||
|
||
/** | ||
* Test shortcode. | ||
* | ||
* Logic for creating the upload object copied from Tests_Media. | ||
* | ||
* @covers AMP_Playlist_Embed_Handler::shortcode() | ||
*/ | ||
public function test_shortcode() { | ||
$id_mp4 = $this->factory->attachment->create_upload_object( DIR_TESTDATA . '/uploads/small-video.mp4' ); | ||
$id_mkv = $this->factory->attachment->create_upload_object( DIR_TESTDATA . '/uploads/small-video.mkv' ); | ||
$ids = array( | ||
$id_mp4, | ||
$id_mkv, | ||
); | ||
$attr = array( | ||
'ids' => implode( ',', $ids ), | ||
'type' => 'video', | ||
); | ||
$playlist = $this->instance->shortcode( $attr ); | ||
$this->assertContains( '<amp-video', $playlist ); | ||
$this->assertContains( '<amp-state', $playlist ); | ||
$this->assertContains( 'small-video', $playlist ); | ||
$this->assertContains( '[src]="playlist0[playlist0.currentVideo].videoUrl"', $playlist ); | ||
$this->assertContains( 'on="tap:AMP.setState({playlist0: {currentVideo: 0}})"', $playlist ); | ||
} | ||
|
||
} |