Symfony2 SonataMediaBundle音频配置

时间:2013-06-03 10:01:40

标签: symfony

我需要使用SonataMediaBundle存储音频文件 - mp3,也可​​能以某种方式将它们转发给ogg。

所以基本上我需要配置。

目前我有这个:

sonata_media:
default_context: default
db_driver: doctrine_orm # or doctrine_mongodb, doctrine_phpcr
contexts:
    default:  # the default context is mandatory
        providers:
            - sonata.media.provider.dailymotion
            - sonata.media.provider.youtube
            - sonata.media.provider.image
            - sonata.media.provider.file

        formats:
            small: { width: 100 , quality: 70}
            big:   { width: 500 , quality: 70}
    user:
        providers:
            - sonata.media.provider.file
        formats:
            mp3: { quality: 100}
            ogg: { quality: 100}

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

filesystem:
    local:
        directory:  %kernel.root_dir%/uploads/media
        create:     true
class:
    media:  Application\Sonata\MediaBundle\Entity\Media

但是当我使用命令时:

php.exe C:\ xampp \ htdocs \ Radiooo \ app \ console sonata:media:add sonata.media.provider.file user C:/test.mp3

我的文件存储方式如45914671541816acb68412cc66ba1a71da3ac7a1.mpga

你能帮我解决我做错的事吗?

1 个答案:

答案 0 :(得分:2)

首先:我完全知道这个问题的创建日期,但我最近偶然发现了同样的问题,我想上传一个mp3文件并将文件扩展名保留为mp3而不是将其切换为MPGA。据我所知,过去三年来源代码中没有简单的解决方案......

我很确定我的解决方案并不是最好的解决方案,但只需要添加少量代码即可完成工作:)

在我的项目中,我必须通过将BinaryContent对象的Media设置为Symfony Request类来上传文件,这会将问题引向此行:

// FileProvider.php#L483
$guesser = ExtensionGuesser::getInstance();
$extension = $guesser->guess($media->getContentType());

FileProvider类从Symfony中获取ExtensionGuesser的实例,让他做一个猜测给定ContentType的扩展名应该是什么的工作:

// MimeTypeExtensionGuesser.php#L623
'audio/mpeg' => 'mpga',

在我看来,如果我们可以添加自己的MimeType->Extension映射,或者只是用配置文件中的一个小变化替换ExtensionGuesser的类,那就太棒了。但是没有人知道像我们这样的三个人不想上传mp3文件并将扩展名切换到mpga ...所以没有像这样的解决方案。

但我们实际上可以更改FileProvider的className,只是覆盖我们想要做的不同的方法:

// app/config/services.yml
parameters:
    sonata.media.provider.file.class: Application\Sonata\MediaBundle\Provider\FileProvider



// Application\Sonata\MediaBundle\Provider\FileProvider:
<?php

namespace Application\Sonata\MediaBundle\Provider;

use Sonata\MediaBundle\Extra\ApiMediaFile;
use Sonata\MediaBundle\Model\MediaInterface;
use Symfony\Component\HttpFoundation\File\MimeType\ExtensionGuesser;
use Symfony\Component\HttpFoundation\Request;

/**
 * Class FileProvider
 *
 * @package Application\Sonata\MediaBundle\Provider
 */
class FileProvider extends \Sonata\MediaBundle\Provider\FileProvider
{
    /**
     * @var array
     */
    protected $contentTypeMapping = [
        'audio/mpeg' => 'mp3'
    ];

    /**
     * Set media binary content according to request content.
     *
     * @param MediaInterface $media
     */
    protected function generateBinaryFromRequest(MediaInterface $media)
    {
        if (php_sapi_name() === 'cli') {
            throw new \RuntimeException('The current process cannot be executed in cli environment');
        }

        if (!$media->getContentType()) {
            throw new \RuntimeException(
                'You must provide the content type value for your media before setting the binary content'
            );
        }

        $request = $media->getBinaryContent();

        if (!$request instanceof Request) {
            throw new \RuntimeException('Expected Request in binary content');
        }

        $content   = $request->getContent();
        $extension = $this->getExtension($media->getContentType());

        $handle = tmpfile();
        fwrite($handle, $content);
        $file = new ApiMediaFile($handle);
        $file->setExtension($extension);
        $file->setMimetype($media->getContentType());

        $media->setBinaryContent($file);
    }

    /**
     * Returns the fileExtension for a given contentType
     *
     * First of all, we have to look at our own mapping and if we have no mapping defined, just use the ExtensionGuesser
     *
     * @param string $contentType
     *
     * @return string
     */
    private function getExtension($contentType)
    {
        if (array_key_exists($contentType, $this->contentTypeMapping)) {
            return $this->contentTypeMapping[$contentType];
        }

        // create unique id for media reference
        $guesser   = ExtensionGuesser::getInstance();
        $extension = $guesser->guess($contentType);

        if (!$extension) {
            throw new \RuntimeException(
                sprintf('Unable to guess extension for content type %s', $contentType)
            );
        }

        return $extension;
    }
}

到目前为止,它的效果非常好,我没有问题:)