我需要使用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
你能帮我解决我做错的事吗?
答案 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;
}
}
到目前为止,它的效果非常好,我没有问题:)