亚马逊 AWS 视频转码功能、AWS Elemental MediaConvert 中创建和管理转码作业
/**
* 视频转码
* @return bool
* @author wzb
* @data 2024/5/30
*/
function videoTranscode(&$data)
{
$fileId = $data['id'] ?? 0;
$fileName = $data['fileName'] ?? '';
$FileInput = $data['FileInput'] ?? ''; // s3://s3桶名/src/080dc06642cf814809b61f7f381fa576.mp4
if (!$fileId || empty($fileName) || empty($FileInput)) {
return true;
}
$configOss = config('aws_oss');
$configOss = $configOss['video_transcode'] ?? [];
$accessKeyId = $configOss['accessKeyId'] ?? ''; // 你的AccessKeyId
$accessKeySecret = $configOss['accessKeySecret'] ?? ''; // 你的AccessKeySecret
$region = $configOss['region'] ?? ''; // 你的Bucket所在地域的域名
$bucket = $configOss['bucket'] ?? ''; // 你的Bucket名字
$stsClient = new StsClient([
'version' => 'latest',//版本
'region' => $region,//区域
'credentials' => new Credentials(
$accessKeyId,//Access key ID
$accessKeySecret,//Secret access key
),
]);
$result = $stsClient->getSessionToken([
'DurationSeconds' => 900,
]);
$credentials = $stsClient->createCredentials($result);
$data['token_data'] = $result['Credentials']['Expiration'] ?? '';
$tokenCredentials = $credentials->toArray();
$data['token_expires_date'] = date('Y-m-d H:i:s', $tokenCredentials['expires'] ?? 0);
$mediaConvertClient = new MediaConvertClient([
'version' => 'latest',//版本
'region' => $region,
// 'endpoint' => 'https://mediaconvert.ap-southeast-1.amazonaws.com',
'credentials' => $credentials
// 'credentials' => [
// 'key' => $result['Credentials']['AccessKeyId'],
// 'secret' => $result['Credentials']['SecretAccessKey'],
// 'token' => $result['Credentials']['SessionToken']
// ]
]);
try {
$outFileDir = [
'oss_path_480' => "s3://{$bucket}/video_test/video480/",
'oss_path_720' => "s3://{$bucket}/video_test/video720/",
'oss_path_1080' => "s3://{$bucket}/video_test/video1080/",
];
$result = $mediaConvertClient->createJob([
"Role" => "arn:aws:iam::51**284:role/service-role/MediaConvert_Default_Role",
"Settings" => [
'FollowSource' => 1,
'Inputs' => [
[
'AudioSelectors' => [
'Audio Selector 1' => [
'DefaultSelection' => 'DEFAULT'
]
],
'VideoSelector' => [],
'TimecodeSource' => 'ZEROBASED',
'FileInput' => $FileInput,
]
],
'OutputGroups' => self::configOutputGroups($outFileDir),
],
"Queue" => "arn:aws:mediaconvert:ap-southeast-1:515287419284:queues/Default",
"UserMetadata" => [
"Customer" => "Amazon1"
],
]);
$jobId = ($result['Job']['Id'] ?? '');
$data['jobId'] = $jobId;
if (!empty($jobId)) {
$res = FileModel::updateData(['id' => $fileId], [
'job_id' => $jobId, 'oss_path_480' => $outFileDir['oss_path_480'] . $fileName,
'oss_path_720' => $outFileDir['oss_path_720'] . $fileName, 'oss_path_1080' => $outFileDir['oss_path_1080'] . $fileName,
]);
send_socket_time_task(['id' => $fileId, 'job_id' => $jobId], 120, 'OssJob');
} else {
$res = FileModel::updateData(['id' => $fileId], ['is_transcode' => 2]); // 转码失败
}
SysComService::fileInfo($fileId, 2); // 清理缓存
} catch (AwsException $e) {
$data['exception'] = $e->getMessage();;
send_dingtalk_develop("filed upload oss error:{$fileId}:;\n" . $e->getMessage());
return false;
}
return true;
}
// 转码输出配置,
// 可以直接在AWS Elemental MediaConvert 配置模版/作业,然后复制json对象
static function configOutputGroups($outFileDir = [])
{
$video480Path = $outFileDir['oss_path_480'] ?? '';
$video720Path = $outFileDir['oss_path_720'] ?? '';
$video1080Path = $outFileDir['oss_path_1080'] ?? '';
$OutputGroups = '[
{
"CustomName": "video480", "Name": "File Group",
"Outputs": [
{
"ContainerSettings": { "Container": "MP4", "Mp4Settings": {} },
"VideoDescription": {
"Width": 480, "Height": 854,
"CodecSettings": {
"Codec": "H_264",
"H264Settings": { "MaxBitrate": 1000000, "RateControlMode": "QVBR", "SceneChangeDetect": "TRANSITION_DETECTION" }
}
},
"AudioDescriptions": [
{
"CodecSettings": {
"Codec": "AAC",
"AacSettings": { "Bitrate": 96000, "CodingMode": "CODING_MODE_2_0", "SampleRate": 48000 }
}
}
]
}
],
"OutputGroupSettings": {
"Type": "FILE_GROUP_SETTINGS",
"FileGroupSettings": {
"Destination": "' . $video480Path . '",
"DestinationSettings": {
"S3Settings": { "StorageClass": "STANDARD" }
}
}
}
},
{
"CustomName": "video720", "Name": "File Group",
"Outputs": [
{
"ContainerSettings": { "Container": "MP4", "Mp4Settings": {} },
"VideoDescription": {
"Width": 720, "Height": 1280,
"CodecSettings": {
"Codec": "H_264",
"H264Settings": { "MaxBitrate": 2500000, "RateControlMode": "QVBR", "SceneChangeDetect": "TRANSITION_DETECTION" }
}
},
"AudioDescriptions": [
{
"CodecSettings": {
"Codec": "AAC",
"AacSettings": { "Bitrate": 96000, "CodingMode": "CODING_MODE_2_0", "SampleRate": 48000 }
}
}
]
}
],
"OutputGroupSettings": {
"Type": "FILE_GROUP_SETTINGS",
"FileGroupSettings": {
"Destination": "' . $video720Path . '",
"DestinationSettings": {
"S3Settings": { "StorageClass": "STANDARD" }
}
}
}
},
{
"CustomName": "video1080", "Name": "File Group",
"Outputs": [
{
"ContainerSettings": { "Container": "MP4", "Mp4Settings": {} },
"VideoDescription": {
"Width": 1080, "Height": 1920,
"CodecSettings": {
"Codec": "H_264",
"H264Settings": { "MaxBitrate": 5000000, "RateControlMode": "QVBR", "SceneChangeDetect": "TRANSITION_DETECTION" }
}
},
"AudioDescriptions": [
{
"CodecSettings": {
"Codec": "AAC",
"AacSettings": { "Bitrate": 96000, "CodingMode": "CODING_MODE_2_0", "SampleRate": 48000 }
}
}
]
}
],
"OutputGroupSettings": {
"Type": "FILE_GROUP_SETTINGS",
"FileGroupSettings": {
"Destination": "' . $video1080Path . '"
}
}
}
]';
return json_decode($OutputGroups, true);
}