1

I need to use SonataMediaBundle to store audio files - mp3 and maybe also somehow conwert them also to ogg.

So basically I need config.

Currently I have this:

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

But when I Im using command:

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

Im getting file stored like 45914671541816acb68412cc66ba1a71da3ac7a1.mpga

Can you help me what Im doing wrong?

4

1 回答 1

2

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

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

BinaryContent在我的项目中,我必须通过将对象的 设置为MediaSymfony类来上传文件Request,这导致问题恰好出现在这一行:

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

该类从 SymfonyFileProvider获取实例,ExtensionGuesser并让他猜测给定 ContentType 的扩展名应该是什么:

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

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

但我们实际上可以更改 classNameFileProvider并覆盖我们想要做不同事情的方法:

// 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;
    }
}

到目前为止,它运行得很好,我对此没有任何问题:)

于 2017-03-29T19:16:26.960 回答