很久沒去參加 AWS 舉辦的一些產品佈道會了,最近因為工作上的需求,需要把影片檔案轉換成串流的格式,還好有想到去年似乎有參加一場 AWS 開發者大會聽到類似這樣的技術,這樣就不用自己很辛苦的架設一台 Streaming Server 了,但是缺點就是當 AWS 的服務用的越爽,就會被 AWS 給綁架,以後沒 AWS 可以用怎麼辦!!!

整個作法其實不算很複雜,但是必須先理解滿多服務如何使用,這裡大致上會使用到的 AWS 服務項目有:S3, Elastic Transcoder, Lambda。

    ● S3 : 儲存空間
    ● Elastic Transcoder : 轉檔服務,可將 S3 上的影音檔轉成各種格式
    ● Lambda : 類似可自行撰寫的 API,來完成一些制式的工作項目

首先,需自行花點時間了解 Elastic Transcoder 的操作與使用,這部份可自行上網找尋相關資訊,或參考 這篇


如果 Elastic Transcoder 都已經了解怎麼操作,就算是已經理解這像轉檔服務的使用方式,接著就是透過 Lambda 的方式將這些工作自動化,所以接下來的重頭戲就是如何撰寫 Lambda 的 function 了,沒記錯的話,目前提供三種語法來撰寫,有 Python、Node.js、Java 三種,就請大家找個自己最熟悉或擅長的程式語言吧!底下我會以 Node.js 的語法來當範例,因為 Python 跟 Java 都很不熟,node.js 至少算是 javascript 的好親戚,平時多少有再寫。


先附上個人參考文獻,其實能力好的,看完這兩篇,大概也不用我多廢話了

Using AWS Lambda for Web Video Transcoding
Automating Transcoding using AWS service (Elastic Transcoder , Lambda, S3 notifications)


底下先來看圖說故事,先到 AWS Lambda 內去建立一個 function,內容是由 S3 bucket 內特定資料夾(video/)內,建立(新增/上傳)了一個 mp4 檔案時,所觸發的條件。

Step 1. Create Lambda function

l01.JPG 

Step 2. 有範例程式就選來用吧!不然就得自己從頭寫,挺麻煩的

l02.JPG 

Step 3. 確定好觸發 Lambda 的條件設定

l03.JPG 

Step 4. 命名以及設定執行 Lambda 的角色權限

l04.JPG 

l05.JPG 

在此提供該角色權限的 Policy

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ],
            "Resource": "arn:aws:logs:*:*:*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:PutObject"
            ],
            "Resource": [
                "arn:aws:s3:::*"
            ]
        },
        {
            "Sid": "Stmt1441234334958",
            "Action": [
                "elastictranscoder:CreateJob"
            ],
            "Effect": "Allow",
            "Resource": "*"
        }
    ]
}

Step 5. 檢查一下所有的設定,沒問題就繼續了!

l06.JPG

Lambda 使用方式
畫面截圖後簡單說明
l08.JPG 

測試檔的用法,左上角的 Action -> Configure test event,然後選澤 S3 Put 的範例來修改,進行測試
請到 S3 上找個檔案來比對修改測試檔範例,改好後測試的結果應該如上一張圖。

l09.JPG l07.JPG 

再熟悉 lambda 的使用方式後,就可以開始撰寫轉檔的部份了,其實就是再 S3 上傳 mp4 檔後,建立一個 Elastic Transcoder 的工作來進行轉檔

console.log('Loading function');
var AWS = require('aws-sdk');
var s3 = new AWS.S3({ apiVersion: '2006-03-01' });
var eltr = new AWS.ElasticTranscoder({
    apiVersion: '2012-09-25',
    region: 'ap-northeast-1'
});
var pipelineId = '1453215075XXX-XXXXXX';  // please use your pipeline id
// System preset: HLS 1.5M
var preset_HLS_15M  = '1351620000001-200020';
// return basename without extension
function basename(path) {
   return path.split('/').reverse()[0].split('.')[0];
}
exports.handler = function(event, context) {
    var bucket = event.Records[0].s3.bucket.name;
    var key    = event.Records[0].s3.object.key;
    var params = {
        Bucket: bucket,
        Key: key
    };
    s3.getObject(params, function(err, data) {
        if (err) {
            console.log(err);
            var message = "Error getting object " + key + " from bucket " + bucket +
                ". Make sure they exist and your bucket is in the same region as this function.";
            console.log(message);
            context.fail(message);
        } else {
            /* Below section can be used if you want to put any check based on metadata */
            if (data.ContentType == 'video/mp4') {
                console.log('Found new video: ' + key + ', sending to ET');
                sendVideoToET(key, context);
            } else {
                console.log('Upload ' + key + 'was not video');
                console.log(JSON.stringify(data.Metadata));
                context.fail();
            }
        }
    });
};
function sendVideoToET(key, context) {
    var params = {
        PipelineId: pipelineId,
        OutputKeyPrefix: null,
        Input: {
            Key: key,
            FrameRate: 'auto',
            Resolution: 'auto',
            AspectRatio: 'auto',
            Interlaced: 'auto',
            Container: 'auto'
        },
        Output: {
            Key: 'stream/' + basename(key),
            ThumbnailPattern: 'stream-thumb/' + basename(key) + '-thumb-{count}',
            PresetId: preset_HLS_15M,
            Rotate: 'auto',
            SegmentDuration: "10"
        }
    };
    eltr.createJob(params, function(err, data) {
        if (err) {
            console.log(err, err.stack); // an error occurred
            context.fail();
        }else {
            console.log("Create Job Success");
            context.succeed();
        }
    });
}

先到自己 S3 bucket 上建立 video 目錄,然後傳個 mp4 擋上去,接著修改一下 test configure 的內容,使用剛剛傳上去的 mp4 檔來測試,當測試成功後,再回到 S3 bucket 內,應該就可以看到轉出來的檔案在 stream 目錄下,以及縮圖在 stream-thumb 下

arrow
arrow

    soarlin 發表在 痞客邦 留言(0) 人氣()