当前位置: 移动技术网 > IT编程>开发语言>c# > DotNet 使用阿里云媒体转码服务

DotNet 使用阿里云媒体转码服务

2019年08月06日  | 移动技术网IT编程  | 我要评论

公司项目中一部分文件放到了阿里云 oss 上,其中有些音频文件是 amr 类型的,在后期使用的时候比较麻烦,所以需要转换成 mp3 的文件,方便以后使用。本来想使用 ffmpeg 处理,但由于文件都存放在阿里云 oss 上,使用 ffmpeg 就需要把文件从远程下载下来,转码之后再重新传回阿里云上,还需要使用消息组件进行通知,而且转码对服务器的压力也会很大。不如直接使用阿里云的媒体转码服务来的快,阿里云只提供了 oss 的 dotnet 类库,并没有提供 mts 的,所以只能自己参考 api 和其他语言的类库来开发,还好 mts 的 api 并不是很复杂,几次尝试之后就搞定了。

相关参数需要从阿里云的控制台获取。

阿里云媒体转码服务类:

   /// <summary>
    /// 阿里云媒体转码服务助手类。
    /// </summary>
    public class mediatranscodehelper
    {

        private static readonly encoding encode_type = encoding.utf8;
        private static readonly string algorithm = "hmacsha1";
        private static readonly string http_method = "get";
        private static readonly string separator = "&";
        private static readonly string equal = "=";
        private static readonly string iso8601_date_format = "yyyy-mm-dd't'hh:mm:ss'z'";
        private static readonly string regionid = "cn-beijing";
        private static readonly string version = "2014-06-18";
        private static readonly string action = "submitjobs";
        private static readonly string format = "json";
        private static readonly string mtsdomain = "mts.cn-beijing.aliyuncs.com";


        private static readonly int maxretrynumber = 3;
        private static readonly bool autoretry = true;
        private static readonly int timeoutinmilliseconds = 100000;


        private static readonly string accesskeyid = "you accesskeyid";
        private static readonly string accesskeysecret = "you accesskeysecret";
        private static readonly string pipelineid = "you pipelineid";


        /// <summary>
        /// 提交转码任务。
        /// </summary>
        /// <param name="inputfile">输入文件。</param>
        /// <returns>输出文件。</returns>
        public static string submittranscodejob(string inputfile, string osslocation)
        {
            string outputjob = string.empty;

            return outputjob;
        }

        /// <summary>
        /// 提交转码任务。
        /// </summary>
        public async task<(bool success, string response)> submittranscodejob()
        {
            string signaturenonce = guid.newguid().tostring();
            var paramers = new dictionary<string, string>
            {
                { "action", action },
                { "version", "2014-06-18" },
                { "accesskeyid", accesskeyid },
                { "timestamp", formatiso8601date(datetime.now) },
                { "signaturemethod", "hmac-sha1" },
                { "signatureversion", "1.0" },
                { "signaturenonce", signaturenonce },
                { "format", format },
                { "pipelineid", pipelineid },
                { "input", "{\"bucket\":\"charlesbeijng\",\"location\":\"oss-cn-beijing\",\"object\":\"3.amr\"}" },
                { "outputbucket", "charlesbeijng" },
                { "outputlocation", "oss-cn-beijing" },
                { "outputs", " [{\"outputobject\":\"" + guid.newguid().tostring() + ".mp3\",\"templateid\":\"1a94dc364cec44708f00367938a0122f\",\"location\":\"oss-cn-beijing\",\"watermarks\":[{\"inputfile\":{\"bucket\":\"charlesbeijng\",\"location\":\"oss-cn-beijing\",\"object\":\"1.png\"},\"watermarktemplateid\":\"c473de87d0504f44be7ebdac1667ab13\"}]}]" }
            };

            try
            {
                string url = getsignurl(paramers, accesskeysecret);

                int retrytimes = 1;
                var reply = await httpgetasync(url);
                while (500 <= reply.statuscode && autoretry && retrytimes < maxretrynumber)
                {
                    url = getsignurl(paramers, accesskeysecret);
                    reply = await httpgetasync(url);
                    retrytimes++;
                }

                if (!string.isnullorempty(reply.response))
                {
                    var res = jsonconvert.deserializeobject<dictionary<string, string>>(reply.response);
                    if (res != null && res.containskey("code") && "ok".equals(res["code"]))
                    {
                        return (true, reply.response);
                    }
                }

                return (false, reply.response);
            }
            catch (exception ex)
            {
                return (false, response: ex.message);
            }
        }

        /// <summary>
        /// 同步请求。
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        private static string httpget(string url)
        {
            httpwebrequest req = (httpwebrequest)webrequest.create(url);
            req.method = http_method;
            req.keepalive = true;
            req.useragent = "idui1";
            req.timeout = timeoutinmilliseconds;
            req.contenttype = "application/x-www-form-urlencoded;charset=utf-8";
            httpwebresponse rsp = null;
            try
            {
                rsp = (httpwebresponse)req.getresponse();
            }
            catch (webexception webex)
            {
                if (webex.status == webexceptionstatus.timeout)
                {
                    rsp.close();
                }
            }

            if (rsp != null)
            {
                if (rsp.characterset != null)
                {
                    encoding encoding = encoding.getencoding(rsp.characterset);
                    return getresponseasstring(rsp, encoding);
                }
                else
                {
                    return string.empty;
                }
            }
            else
            {
                return string.empty;
            }
        }

        /// <summary>
        /// 异步请求。
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        private async task<(int statuscode, string response)> httpgetasync(string url)
        {
            httpclienthandler handler = new httpclienthandler();
            handler.proxy = null;
            handler.automaticdecompression = decompressionmethods.gzip;

            using (var http = new httpclient(handler))
            {
                http.timeout = new timespan(timespan.tickspermillisecond * timeoutinmilliseconds);
                httpresponsemessage response = await http.getasync(url);
                return ((int)response.statuscode, await response.content.readasstringasync());
            }
        }

        /// <summary>
        /// 把响应流转换为文本。
        /// </summary>
        /// <param name="rsp">响应流对象</param>
        /// <param name="encoding">编码方式</param>
        /// <returns>响应文本</returns>
        private static string getresponseasstring(httpwebresponse rsp, encoding encoding)
        {
            stringbuilder result = new stringbuilder();
            stream stream = null;
            streamreader reader = null;

            try
            {

                // 以字符流的方式读取http响应
                stream = rsp.getresponsestream();
                //rsp.close();
                reader = new streamreader(stream, encoding);

                // 每次读取不大于256个字符,并写入字符串
                char[] buffer = new char[256];
                int readbytes = 0;
                while ((readbytes = reader.read(buffer, 0, buffer.length)) > 0)
                {
                    result.append(buffer, 0, readbytes);
                }
            }
            catch (webexception webex)
            {
                if (webex.status == webexceptionstatus.timeout)
                {
                    result = new stringbuilder();
                }
            }
            finally
            {
                // 释放资源
                if (reader != null) reader.close();
                if (stream != null) stream.close();
                if (rsp != null) rsp.close();
            }

            return result.tostring();
        }

        /// <summary>
        /// 处理消息。
        /// </summary>
        /// <param name="message">消息内容。</param>
        public static void handlingmessage(string message)
        {

        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="datetime"></param>
        /// <returns></returns>
        private static string formatiso8601date(datetime datetime)
        {
            return datetime.touniversaltime().tostring("yyyy-mm-dd't'hh:mm:ss'z'", cultureinfo.createspecificculture("en-us"));
        }


        /// <summary>
        /// 签名
        /// </summary>
        public static string signstring(string source, string accesssecret)
        {
            using (var algorithm = new hmacsha1(encoding.utf8.getbytes(accesssecret.tochararray())))
            {
                return convert.tobase64string(algorithm.computehash(encoding.utf8.getbytes(source.tochararray())));
            }
        }


        private string getsignurl(dictionary<string, string> parameters, string accesssecret)
        {
            var imutablemap = new dictionary<string, string>(parameters)
            {
                //{ "timestamp", formatiso8601date(datetime.now) },
                //{ "signaturemethod", "hmac-sha1" },
                //{ "signatureversion", "1.0" },
                //{ "signaturenonce", guid.newguid().tostring() },
                //{ "action", action },
                //{ "version", version },
                //{ "format", format },
                //{ "regionid", regionid }
            };

            idictionary<string, string> sorteddictionary = new sorteddictionary<string, string>(imutablemap, stringcomparer.ordinal);
            stringbuilder canonicalizedquerystring = new stringbuilder();
            foreach (var p in sorteddictionary)
            {
                canonicalizedquerystring.append("&")
                .append(percentencode(p.key)).append("=")
                .append(percentencode(p.value));
            }

            stringbuilder stringtosign = new stringbuilder();
            stringtosign.append(http_method);
            stringtosign.append(separator);
            stringtosign.append(percentencode("/"));
            stringtosign.append(separator);
            stringtosign.append(percentencode(canonicalizedquerystring.tostring().substring(1)));

            string signature = signstring(stringtosign.tostring(), accesssecret + "&");

            imutablemap.add("signature", signature);

            return composeurl(mtsdomain, imutablemap);
        }
        private static string composeurl(string endpoint, dictionary<string, string> parameters)
        {
            stringbuilder urlbuilder = new stringbuilder("");
            urlbuilder.append("http://").append(endpoint);
            if (-1 == urlbuilder.tostring().indexof("?"))
            {
                urlbuilder.append("/?");
            }
            string query = concatquerystring(parameters);
            return urlbuilder.append(query).tostring();
        }
        private static string concatquerystring(dictionary<string, string> parameters)
        {
            if (null == parameters)
            {
                return null;
            }
            stringbuilder sb = new stringbuilder();

            foreach (var entry in parameters)
            {
                string key = entry.key;
                string val = entry.value;

                sb.append(httputility.urlencode(key, encoding.utf8));
                if (val != null)
                {
                    sb.append("=").append(httputility.urlencode(val, encoding.utf8));
                }
                sb.append("&");
            }

            int strindex = sb.length;
            if (parameters.count > 0)
                sb.remove(strindex - 1, 1);

            return sb.tostring();
        }

        public static string percentencode(string value)
        {
            stringbuilder stringbuilder = new stringbuilder();
            string text = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz0123456789-_.~";
            byte[] bytes = encoding.getencoding("utf-8").getbytes(value);
            foreach (char c in bytes)
            {
                if (text.indexof(c) >= 0)
                {
                    stringbuilder.append(c);
                }
                else
                {
                    stringbuilder.append("%").append(
                        string.format(cultureinfo.invariantculture, "{0:x2}", (int)c));
                }
            }
            return stringbuilder.tostring();
        }
        /// <summary>
        /// hmac-sha1加密算法
        /// </summary>
        /// <param name="key">密钥</param>
        /// <param name="input">要加密的串</param>
        /// <returns></returns>
        public static string hmacsha1(string key, string input)
        {
            byte[] keybytes = encoding.utf8.getbytes(key);
            byte[] inputbytes = encoding.utf8.getbytes(input);
            hmacsha1 hmac = new hmacsha1(keybytes);
            byte[] hashbytes = hmac.computehash(inputbytes);
            return convert.tobase64string(hashbytes);
        }
        /// <summary>
        /// aes 算法加密(ecb模式) 将明文加密,加密后进行base64编码,返回密文
        /// </summary>
        /// <param name="encryptstr">明文</param>
        /// <param name="key">密钥</param>
        /// <returns>加密后base64编码的密文</returns>
        public static string encrypt(string encryptstr, string key)
        {
            try
            {
                //byte[] keyarray = encoding.utf8.getbytes(key);
                byte[] keyarray = convert.frombase64string(key);
                byte[] toencryptarray = encoding.utf8.getbytes(encryptstr);

                rijndaelmanaged rdel = new rijndaelmanaged
                {
                    key = keyarray,
                    mode = ciphermode.ecb,
                    padding = paddingmode.pkcs7
                };

                icryptotransform ctransform = rdel.createencryptor();
                byte[] resultarray = ctransform.transformfinalblock(toencryptarray, 0, toencryptarray.length);

                return convert.tobase64string(resultarray, 0, resultarray.length);
            }
            catch (exception)
            {
                return null;
            }
        }

        public static string decrypt(string todecrypt, string key)
        {
            byte[] keyarray = convert.frombase64string(key); // 将 testgenaesbytekey 类输出的字符串转为 byte 数组
            byte[] toencryptarray = convert.frombase64string(todecrypt);
            rijndaelmanaged rdel = new rijndaelmanaged
            {
                key = keyarray,
                mode = ciphermode.ecb,        // 必须设置为 ecb
                padding = paddingmode.pkcs7  // 必须设置为 pkcs7
            };
            icryptotransform ctransform = rdel.createdecryptor();
            byte[] resultarray = ctransform.transformfinalblock(toencryptarray, 0, toencryptarray.length);
            return encoding.utf8.getstring(resultarray);
        }
        private static string buildcanonicalizedquerystring(dictionary<string, string> parameters)
        {
            // 对参数进行排序
            list<string> sortedkeys = new list<string>(parameters.keys);
            sortedkeys.sort();

            stringbuilder temp = new stringbuilder();

            foreach (var key in sortedkeys)
            {
                // 此处需要对 key 和 value 进行编码
                string value = parameters[key];
                temp.append(separator).append(percentencode(key)).append(equal).append(percentencode(value));
            }
            return temp.tostring().substring(1);
        }


        private static string buildrequesturl(string signature, dictionary<string, string> parameters)
        {
            // 生成请求 url
            stringbuilder temp = new stringbuilder("mts.cn-beijing.aliyuncs.com");
            temp.append(httputility.urlencode("signature", encode_type)).append("=").append(signature);
            foreach (var item in parameters)
            {
                temp.append("&").append(percentencode(item.key)).append("=").append(percentencode(item.value));
            }
            return temp.tostring();
        }
    }

使用的时候直接调用 submittranscodejob 方法就可以了。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网