我在我的项目中使用 Sonata Media Bundle 和 Symfony2.3。当我覆盖 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 提供商相同。
将相同的服务名称和提供商名称写入我们的捆绑包中,然后问题就解决了。
就像您扩展 YoutubeProvider 一样,然后在您的包中写入相同的提供商名称。
看这个:
我的配置.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
}
这不是完全重新定义供应商服务的最佳方式 - 这可能行不通。
在这种情况下有一些常见的做法(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);
}
}