Osadzanie filmów z YouTube i DailyMotion

by Mateusz Tymek — on Zend Framework, PHP

Head's up! This post was written back in 2009 and is very likely to contain outdated information.

Logo YouTubeWitam ponownie po nieco długiej, wakacyjnej przerwie. Dzisiaj przedstawiam kod który pozwoli łatwo i szybko osadzić na naszej stronie filmik z serwisów YouTube czy DailyMotion (jednocześnie bardzo łatwo można go rozszerzyć o inne strony hostujące wideo).

Problem można podejść na kilka sposobów jednak najbardziej elegancki to napisanie pomocnika widoku (Zend_View_Helper_*).

Element wiążący naszą stronę z hostingiem wideo to identyfikator filmu (videoId). Przykładowy odnośnik z YouTube wygląda tak:

http://www.youtube.com/watch?v=9PLBxoy1q0A

Ciąg znaków 9PLBxoy1q0A jest identyfikatorem filmu. Będzie pierwszym argumentem wymaganym przez nasz helper.  Ponieważ rozwiązanie ma być uniwersalne (nie chcemy być ograniczeni do YouTube), helper musi pobierać jeszcze jeden argument, określający serwis z którego korzystamy.

Z takimi założeniami będziemy osadzali wideo w następujący sposób:

<?php
// videoId - 9PLBxoy1q0A, serwis: YouTube
echo $this->flashVideoPlayer('9PLBxoy1q0A')->setType('yt'); ?>

Dodajmy jeszcze możliwość ustalenia rozmiaru wyświetlanego playera:

<?php
// videoId - xanl4t, serwis: DailyMotion, rozmiar: 400x300px
echo $this->flashVideoPlayer('xanl4t')->setType('dm')->setSize(400, 300); ?>

Czas na przedstawienie kodu rozwiazania. Będzie się składał z jednej klasy głównej (Zend_View_Helper_FlashVideoPlayer) oraz dwóch pomocniczych - po jednej dla każdego obsługiwanego serwisu.

Oto główna klasa:

<?php
// FlashVideoPlayer.php
class Zend_View_Helper_FlashVideoPlayer extends Zend_View_Helper_Abstract
{
    /**
     * Avalilable players
     */
    const YOUTUBE     = 'yt';
    const DAILYMOTION = 'dm';

    /**
     *
     * @var My_View_Helper_FlashVideoPlayer_*
     */
    protected $_player;

    /** Player size */
    protected $_width   = 400;
    protected $_height  = 280;

    /** Player type */
    protected $_type    = 'yt';  // default: You Tube

    /** VideoId */
    protected $_videoId;

    /** Mutators */
    public function setSize($width, $height)
    {
        $this->_width = $width;
        $this->_height = $height;
        return $this;
    }

    public function getWidth()
    {
        return $this->_width;
    }

    public function getHeight()
    {
        return $this->_height;
    }

    public function setVideoId($id)
    {
        $this->_videoId = $id;
        return $this;
    }

    public function getVideoId()
    {
        return $this->_videoId;
    }

    public function setType($type)
    {
        $this->_type = $type;
        return $this;
    }

    public function getType()
    {
        return $this->_type;
    }

    /** Setup video ID */
    public function flashVideoPlayer($videoId = null)
    {
        if (null !== $videoId) {
            $this->setVideoId($videoId);
        }
        return $this;
    }

    /**
     * Returns class responsible for rendering given player type
     * @return My_View_Helper_FlashVideoPlayer_*
     */
    public function getPlayer()
    {
        if (null === $this->_player) {
            $class = 'My_View_Helper_FlashVideoPlayer_'.ucfirst($this->getType());
            $this->_player = new $class($this);
        }
        return $this->_player;
    }

    /** Returns string representation of an object */
    public function  __toString()
    {
        return $this->getPlayer()->__toString();
    }
}

Plik FlashVideoPlayer.php najlepiej będzie umieścić w katalogu /application/view/scripts - jeżeli korzystamy z ZF w wersji conajmniej 1.8 i klasy Zend_Application, to pomocnik będzie automagicznie dostępny w skryptach widoku.

Następne dwie klasy mają za zadanie dostarczyć kod HTML wyświetlający odtwarzacz. Rozwiązanie dla YouTube:

<?php

/**
 * Displays YouTube video player
 */
class My_View_Helper_FlashVideoPlayer_Yt
{
    protected $_viewHelper;

    public function __construct($viewHelper)
    {
        $this->_viewHelper = $viewHelper;
    }

    public function __toString()
    {
        $width   = $this->_viewHelper->getWidth();
        $height  = $this->_viewHelper->getHeight();
        $videoId = $this->_viewHelper->getVideoId();
        return <<<STOP
<object width="$width" height="$height">
    <param name="movie" value="http://www.youtube.com/v/$videoId&hl=pl&fs=1"></param>
    <param name="allowFullScreen" value="true"></param>
    <param name="allowscriptaccess" value="always"></param>
    <embed src="http://www.youtube.com/v/$videoId&hl=pl&fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="<?= $width ?>" height="<?= $height ?>"></embed>
</object>
STOP;
    }
}

Analogiczne - dla DailyMotion:

<?php

/**
 * Displays DailyMotion video player
 */

class Mango_View_Helper_FlashVideoPlayer_Dm
{
    protected $_viewHelper;

    public function __construct($viewHelper)
    {
        $this->_viewHelper = $viewHelper;
    }

    public function __toString()
    {
        $width   = $this->_viewHelper->getWidth();
        $height  = $this->_viewHelper->getHeight();
        $videoId = $this->_viewHelper->getVideoId();
        return <<<STOP
<object width="$width" height="$height">
    <param name="movie" value="http://www.dailymotion.pl/swf/$videoId&colors=special:BAAC7D;&related=1" />
    <param name="allowFullScreen" value="true"/>
    <param name="allowScriptAccess" value="always"/>
    <embed src="http://www.dailymotion.pl/swf/$videoId&colors=special:BAAC7D;&related=1"
           type="application/x-shockwave-flash"
           width="$width"
           height="$height"
           allowFullScreen="true"
           allowScriptAccess="always">
    </embed>
</object>
STOP;
    }
}

Co dalej?

Przed wdrożeniem rozwiązanie powinno zostać nieco dopracowane. Przede wszystkim metoda setType powina sprawdzać czy obsługa danego playera jest zaimplementowana (aktualnie przyjmie dowolny ciąg znaków, a wyjątek zostanie wygenerowany dopiero przy próbie wyświetlenia odtwarzacza). Można pokusić się o dodanie większej liczby opcji (np. zmiana koloru playera czy opcja odtwarzania filmów w wysokiej rozdzielczości). Wreszcie, można dodać klasy obsługujące inne serwisy.


comments powered by Disqus