未生成缩略图

Posted

技术标签:

【中文标题】未生成缩略图【英文标题】:No thumbnails generated 【发布时间】:2013-11-23 09:26:33 【问题描述】:

我在我的项目中使用带有 Symfony2.3 的 Sonata Media Bundle。当我覆盖 youtube 提供商 sonata.media.provider.youtube 时。一切正常。没有错误或任何东西,但在

 /Web/uploads/media 

没有生成缩略图,但在我的管理仪表板中显示:

 /uploads/media/default/0001/01/thumb_9_default_small.jpg.

我不知道如何,但是当我不覆盖 sonata.media.provider.youtube 时,缩略图会在

中生成
/web/uploads/media/ 

喜欢:

/web/uploads/media/default/0001/01/thumb_9_default_small.jpg.

不知道为什么?

这是我创建自定义服务提供者的配置文件:

services:
    sonata.media.provider.youtubecustom:
          class: %application_sonata_media.youtubecustom_class%
          tags:
              -  name: sonata.media.provider 
          arguments:
              - sonata.media.provider.youtubecustom
              - @sonata.media.filesystem.local
              - @sonata.media.cdn.server
              - @sonata.media.generator.default
              - @sonata.media.thumbnail.format
              - @sonata.media.buzz.browser
              - @sonata.media.metadata.proxy

          calls:
              - [ setTemplates, [  helper_thumbnail: SonataMediaBundle:Provider:thumbnail.html.twig,helper_view: SonataMediaBundle:Provider:view_youtube.html.twig  ] ]

parameters:
    application_sonata_media.youtubecustom_class: Application\Sonata\MediaBundle\Provider\YoutubeCustomProvider

还有 SonataMedia.yml :

sonata_media:
db_driver:       doctrine_orm # | doctrine_mongodb
default_context: default
contexts:
    default:  # the default context is mandatory
        download:
            mode: http # X-Sendfile | http
        providers:
            - sonata.media.provider.youtubecustom
            #- sonata.media.provider.youtube
            - sonata.media.provider.image
            #- sonata.media.provider.file
            #- sonata.media.provider.vimeo

        formats:
            small:  width: 100, quality: 100
            big:    width: 820 , quality: 100

    news:
        providers:
            - sonata.media.provider.image

        formats:
            abtract:  width: 100, quality: 100
            wide:     width: 820 , quality: 100

cdn:
    server:
        path: /uploads/media # http://media.sonata-project.org/

filesystem:
    # define where the uploaded file will be stored
    local:
        directory:  %kernel.root_dir%/../web/uploads/media
        create:     true

providers:
    file:
        resizer:    false

pixlr:
    enabled:  true
    referrer: Demo - Sonata Project

resizer:
    simple:
       #mode:  outbound
        mode:  inset
# Enable Doctrine to map the provided entities
doctrine:
    orm:
       entity_managers:
           default:
               mappings:
                   ApplicationSonataMediaBundle: ~
                   #SonataMediaBundle: ~

我的自定义 youtube 提供程序文件:

<?php

namespace Application\Sonata\MediaBundle\Provider;

use Sonata\MediaBundle\Model\MediaInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Gaufrette\Filesystem;
use Sonata\MediaBundle\CDN\CDNInterface;
use Sonata\MediaBundle\Generator\GeneratorInterface;
use Buzz\Browser;
use Sonata\MediaBundle\Thumbnail\ThumbnailInterface;
use Sonata\MediaBundle\Metadata\MetadataBuilderInterface;
use Sonata\MediaBundle\Provider\YouTubeProvider;

class YoutubeCustomProvider extends YouTubeProvider


/* @var boolean */
protected $html5;

/**
 * @param string                                                $name
 * @param \Gaufrette\Filesystem                                 $filesystem
 * @param \Sonata\MediaBundle\CDN\CDNInterface                  $cdn
 * @param \Sonata\MediaBundle\Generator\GeneratorInterface      $pathGenerator
 * @param \Sonata\MediaBundle\Thumbnail\ThumbnailInterface      $thumbnail
 * @param \Buzz\Browser                                         $browser
 * @param \Sonata\MediaBundle\Metadata\MetadataBuilderInterface $metadata
 * @param boolean                                               $html5
 */
public function __construct($name, Filesystem $filesystem, CDNInterface $cdn, GeneratorInterface $pathGenerator, ThumbnailInterface $thumbnail, Browser $browser, MetadataBuilderInterface $metadata = null, $html5 = false)

    parent::__construct($name, $filesystem, $cdn, $pathGenerator, $thumbnail, $browser, $metadata);
    $this->html5 = $html5;


/**
 * @inheritdoc
 */
public function getHelperProperties(MediaInterface $media, $format, $options = array())


    // Override html5 value if $options['html5'] is a boolean
    if (!isset($options['html5'])) 
        $options['html5'] = $this->html5;
    

    // documentation : http://code.google.com/apis/youtube/player_parameters.html

    $default_player_url_parameters = array(

        //Values: 0 or 1. Default is 1. Sets whether the player should load related
        // videos once playback of the initial video starts. Related videos are
        // displayed in the "genie menu" when the menu button is pressed. The player
        // search functionality will be disabled if rel is set to 0.
        'rel'               => 0,

        // Values: 0 or 1. Default is 0. Sets whether or not the initial video will autoplay
        // when the player loads.
        'autoplay'          => 0,

        // Values: 0 or 1. Default is 0. In the case of a single video player, a setting of 1
        // will cause the player to play the initial video again and again. In the case of a
        // playlist player (or custom player), the player will play the entire playlist and
        // then start again at the first video.
        'loop'              => 0,

        // Values: 0 or 1. Default is 0. Setting this to 1 will enable the javascript API.
        // For more information on the Javascript API and how to use it, see the JavaScript
        // API documentation.
        'enablejsapi'       => 0,

        // Value can be any alphanumeric string. This setting is used in conjunction with the
        // JavaScript API. See the JavaScript API documentation for details.
        'playerapiid'    => null,

        // Values: 0 or 1. Default is 0. Setting to 1 will disable the player keyboard controls.
        // Keyboard controls are as follows:
        //      Spacebar: Play / Pause
        //      Arrow Left: Jump back 10% in the current video
        //      Arrow Right: Jump ahead 10% in the current video
        //      Arrow Up: Volume up
        //      Arrow Down: Volume Down
        'disablekb'      => 0,

        // Values: 0 or 1. Default is 0. Setting to 1 enables the "Enhanced Genie Menu". This
        // behavior causes the genie menu (if present) to appear when the user's mouse enters
        // the video display area, as opposed to only appearing when the menu button is pressed.
        'egm'               => 0,

        // Values: 0 or 1. Default is 0. Setting to 1 enables a border around the entire video
        // player. The border's primary color can be set via the color1 parameter, and a
        // secondary color can be set by the color2 parameter.
        'border' => 0,

        // Values: Any RGB value in hexadecimal format. color1 is the primary border color, and
        // color2 is the video control bar background color and secondary border color.
        'color1'            => null,
        'color2'            => null,

        // Values: 0 or 1. Default is 0. Setting to 1 enables the fullscreen button. This has no
        // effect on the Chromeless Player. Note that you must include some extra arguments to
       // your embed code for this to work.
        'fs'             => 1,

        // Values: A positive integer. This parameter causes the player to begin playing the video
        // at the given number of seconds from the start of the video. Note that similar to the
        // seekTo function, the player will look for the closest keyframe to the time you specify.
        // This means sometimes the play head may seek to just before the requested time, usually
        // no more than ~2 seconds
        'start'             => 0,

        // Values: 0 or 1. Default is 0. Setting to 1 enables HD playback by default. This has no
        // effect on the Chromeless Player. This also has no effect if an HD version of the video
        // is not available. If you enable this option, keep in mind that users with a slower
        // connection may have an sub-optimal experience unless they turn off HD. You should ensure
        // your player is large enough to display the video in its native resolution.
        'hd'                => 1,

        // Values: 0 or 1. Default is 1. Setting to 0 disables the search box from displaying when
        // the video is minimized. Note that if the rel parameter is set to 0 then the search box
        // will also be disabled, regardless of the value of showsearch.
        'showsearch'        => 0,

        // Values: 0 or 1. Default is 1. Setting to 0 causes the player to not display information
        // like the video title and rating before the video starts playing.
        'showinfo'          => 0,

        // Values: 1 or 3. Default is 1. Setting to 1 will cause video annotations to be shown by
        // default, whereas setting to 3 will cause video annotation to not be shown by default.
        'iv_load_policy'    => 1,

        // Values: 1. Default is based on user preference. Setting to 1 will cause closed captions
        // to be shown by default, even if the user has turned captions off.
        'cc_load_policy' => 1,

        // Values: 'window' or 'opaque' or 'transparent'.
        // When wmode=window, the Flash movie is not rendered in the page.
        // When wmode=opaque, the Flash movie is rendered as part of the page.
        // When wmode=transparent, the Flash movie is rendered as part of the page.
        'wmode' => 'window'

    );

    $default_player_parameters = array(

        // Values: 0 or 1. Default is 0. Setting to 1 enables a border around the entire video
        // player. The border's primary color can be set via the color1 parameter, and a
        // secondary color can be set by the color2 parameter.
        'border'            => $default_player_url_parameters['border'],

        // Values: 'allowfullscreen' or empty. Default is 'allowfullscreen'. Setting to empty value disables
        //  the fullscreen button.
        'allowFullScreen'   => $default_player_url_parameters['fs'] == '1' ? true : false,

        // The allowScriptAccess parameter in the code is needed to allow the player SWF to call
        // functions on the containing HTML page, since the player is hosted on a different domain
        // from the HTML page.
        'allowScriptAccess' => isset($options['allowScriptAccess']) ? $options['allowScriptAccess'] : 'always',

        // Values: 'window' or 'opaque' or 'transparent'.
        // When wmode=window, the Flash movie is not rendered in the page.
        // When wmode=opaque, the Flash movie is rendered as part of the page.
        // When wmode=transparent, the Flash movie is rendered as part of the page.
        'wmode' => $default_player_url_parameters['wmode']

    );

    $player_url_parameters = array_merge($default_player_url_parameters, isset($options['player_url_parameters']) ? $options['player_url_parameters'] : array());

    $box = $this->getBoxHelperProperties($media, $format, $options);

    $player_parameters = array_merge($default_player_parameters, isset($options['player_parameters']) ? $options['player_parameters'] : array(), array(
        'width' => $box->getWidth(),
        'height' => $box->getHeight()
    ));

    $params = array(
        'html5' => $options['html5'],
        'player_url_parameters' => http_build_query($player_url_parameters),
        'player_parameters' => $player_parameters
    );

    return $params;


/**
 * @inheritdoc
 */
protected function fixBinaryContent(MediaInterface $media)

    if (!$media->getBinaryContent()) 
        return;
    

    if (preg_match("/(?<=v(\=|\/))([-a-zA-Z0-9_]+)|(?<=youtu\.be\/)([-a-zA-Z0-9_]+)/", $media->getBinaryContent(), $matches)) 
        $media->setBinaryContent($matches[2]);
    


/**
 * @inheritdoc
 */
protected function doTransform(MediaInterface $media)

    $this->fixBinaryContent($media);

    if (!$media->getBinaryContent()) 
        return;
    

    $media->setProviderName($this->name);
    $media->setProviderStatus(MediaInterface::STATUS_OK);
    $media->setProviderReference($media->getBinaryContent());

    $this->updateMetadata($media, true);


/**
 * @inheritdoc
 */
public function updateMetadata(MediaInterface $media, $force = false)

    $url = sprintf('http://www.youtube.com/oembed?url=http://www.youtube.com/watch?v=%s&format=json', $media->getProviderReference());

    try 
        $metadata = $this->getMetadata($media, $url);
     catch (\RuntimeException $e) 
        $media->setEnabled(false);
        $media->setProviderStatus(MediaInterface::STATUS_ERROR);

        return;
    

    $media->setProviderMetadata($metadata);

    if ($force) 
        $media->setName($metadata['title']);
        $media->setAuthorName($metadata['author_name']);
    

    $media->setHeight($metadata['height']);
    $media->setWidth($metadata['width']);
    $media->setContentType('video/x-flv');


/**
 * @inheritdoc
 */
public function getDownloadResponse(MediaInterface $media, $format, $mode, array $headers = array())

    return new RedirectResponse(sprintf('http://www.youtube.com/watch?v=%s', $media->getProviderReference()), 302, $headers);



以及由 Sonata Media Bundle 创建的默认 youtube 服务,我将覆盖它:

        <service id="sonata.media.provider.youtube" class="%sonata.media.provider.youtube.class%">
        <tag name="sonata.media.provider" />
        <argument>sonata.media.provider.youtube</argument>
        <argument />
        <argument />
        <argument />
        <argument type="service" id="sonata.media.thumbnail.format" />
        <argument type="service" id="sonata.media.buzz.browser" />
        <argument type="service" id="sonata.media.metadata.proxy" />
        <argument />
        <call method="setTemplates">
            <argument type="collection">
                <argument key='helper_thumbnail'>SonataMediaBundle:Provider:thumbnail.html.twig</argument>
                <argument key='helper_view'>SonataMediaBundle:Provider:view_youtube.html.twig</argument>
            </argument>
        </call>
    </service>

我的服务提供商与默认的 youtube 提供商相同。

【问题讨论】:

【参考方案1】:

在我们的包中写入相同的服务名称和提供者名称,然后问题就解决了。

如果你扩展 YoutubeProvider,那么在你的包中写入相同的提供者名称。

看这个:

我的 Config.yml

services:

    sonata.media.provider.youtube:
          class: %application_sonata_media.youtube_class%
          tags:
              -  name: sonata.media.provider 
          arguments:
              - sonata.media.provider.youtube
              - @sonata.media.filesystem.local
              - @sonata.media.cdn.server
              - @sonata.media.generator.default
              - @sonata.media.thumbnail.format
              - @sonata.media.buzz.browser
              - @sonata.media.metadata.proxy

          calls:
              - [ setTemplates, [  helper_thumbnail: SonataMediaBundle:Provider:thumbnail.html.twig,helper_view: SonataMediaBundle:Provider:view_youtube.html.twig  ] ]

parameters:
    application_sonata_media.youtube_class: Application\Sonata\MediaBundle\Provider\YoutubeProvider

我的 YoutubeProvider.php

<?php

namespace Application\Sonata\MediaBundle\Provider;

use Symfony\Component\HttpFoundation\RedirectResponse;
use Gaufrette\Filesystem;
use Sonata\MediaBundle\CDN\CDNInterface;
use Sonata\MediaBundle\Generator\GeneratorInterface;
use Buzz\Browser;
use Sonata\MediaBundle\Thumbnail\ThumbnailInterface;
use Sonata\MediaBundle\Metadata\MetadataBuilderInterface;
use Sonata\MediaBundle\Provider\YouTubeProvider as MainYouTubeProvider;
use Sonata\AdminBundle\Form\FormMapper;
use Symfony\Component\Form\FormBuilder;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\Constraints\NotNull;
use Sonata\MediaBundle\Model\MediaInterface;

class YoutubeProvider extends MainYouTubeProvider

     //write provider functions

【讨论】:

我也有同样的问题。你能更具体地回答你的问题吗?谢谢。 昆瓦尔·悉达斯·辛格,谢谢。奇迹般有效!在您编辑答案之前,我花了很多时间来解决这个问题。再次感谢。【参考方案2】:

这不是完全重新定义供应商服务的最佳方式 - 这可能行不通。

在这种情况下有一些常见的做法 (http://symfony.com/doc/current/cookbook/bundles/override.html#services-configuration)。

如果你只想重新定义提供者类而不改变服务定义,你只需要改变参数sonata.media.provider.youtube.class的值。

如果您想重新定义供应商服务的某些部分(调用、标签等),最好使用 CompilerPass。

namespace Acme\DemoBundle\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;

class OverrideServiceCompilerPass implements CompilerPassInterface

    public function process(ContainerBuilder $container)
    
        $definition = $container->getDefinition('sonata.media.provider.youtube');
        $definition->addTag($name, $attributes);
    


【讨论】:

以上是关于未生成缩略图的主要内容,如果未能解决你的问题,请参考以下文章

时间戳未打印在 FFMPEG 的缩略图上

引导缩略图列表未显示缩略图

Android 中实现选择图片生成缩略图点击查看大图的功能

使用简单缩略图为 Tastypie API 生成缩略图

Youtube 未加载高分辨率缩略图

Java生成缩略图之Thumbnailator