Web 播放聲音 — Flash 篇 (播放 AMR、WAV)

来源:http://www.cnblogs.com/yuhongda0315/archive/2016/02/28/5224450.html
-Advertisement-
Play Games

本文主要介紹 Flash 播放 AMR 格式 Base64碼 音頻。 在此之前麽有接觸過 Flash ,接觸 AS3 是一頭霧水,不過幸好有 TypeScript 和 JavaScript 的基礎看起來不是很費勁,現學現賣的就是開了 ”跳坑“ 之旅~~~ 1、實現思路 起初一點實現思路都木有,不知道


本文主要介紹 Flash 播放 AMR 格式 Base64碼 音頻。

在此之前麽有接觸過 Flash ,接觸 AS3 是一頭霧水,不過幸好有 TypeScript 和 JavaScript 的基礎看起來不是很費勁,現學現賣的就是開了 ”跳坑“ 之旅~~~

1、實現思路

  起初一點實現思路都木有,不知道該從何做起,只知道用 Flash 播放 AMR ,度娘谷姐的一頓找,結果可想而知,沒有糟糕,只有十分糟糕,哈哈。

  後來想了想,凡事都得有個思路,不能悶頭乾,瞬間恍然大悟,為自己浪費的快一天的時間,感到羞愧和害怕.....

  ① Flash 都能播放哪些音頻。

  ② 在 ActionScript 中AMR 是如何轉換成 Flash 可播放的音頻的。

  ③ JS 中如何調用 ActionScript 中方法,如何交互。

  ④ 如何把 SWF 文件嵌入到 HTML 頁面中。

  ⑤ 如何把 AMR(Audio) 和 Flash 播放AMR 兩種方式封裝起來。

2、逐一破解

  ① Flash 都能播放哪些音頻:

    MP3 格式是 Flash 預設支持的音頻格式,WAVE 格式需要轉換可以播放,其他格式也是需要轉換的,因為先做的 Chrome 下播放聲音,對 WAVE 音頻多少有些瞭解,所    以決定從 WAVE 音頻入手,所以按照上述的套路來 ”屢思路“:

     (1) 不管如何轉換,肯定要操作位元組數組,所以第一步把 AMR 格式的 base64 碼 轉換為 ByteArray 數組。

     (2) 如何把 AMR 的 ByteArray 轉換成 WAVE 格式的 ByteArray 數組,毫無疑問 ,肯定需要解碼的過程。

    按照這兩個小步驟逐一做,很快找到了 base64 的轉碼過程(開始是自己用 AS 實現了 JS 中的的 轉碼過程,可用但不完美,最終借鑒 github 上大牛的轉換過程),

    但 AMR 轉換 WAVE 這個就沒有那麼容易了,最終確定,AS 解 AMR 比較費勁,需要 用 C 語言來解碼,然後用 CrossBirdge 生成可以供 Flash 調用的 SWC 文件。

    ok,到這為止,第一步就完美解決了。

  ② 在 ActionScript 中AMR 是如何轉換成 Flash 可播放的音頻的:

    上文中有提到,需要用 C 語言 進行對 AMR 解碼,下文中會給出 C 語言解碼和生成 SWC 的教程(借鑒大牛的)。

  ③ JS 中如何調用 ActionScript 中方法,如何交互,下文中會貼出完整代碼(一定要看註釋、註釋、註釋),此處寫出 JS 調用過程。

    JS代碼:

function callFlashMethod() {
  // play 是 flash 代碼中定義的 ExternalInterface.addCallback("play",this.play); 下文中會有詳細介紹。
  thisMovie("嵌入頁面上<object>的ID").play("base64str");
}

function thisMovie(movieName) {
    if (navigator.appName.indexOf("Microsoft") != -1) {
        return window[movieName]
    }
    else {
        return document[movieName]
    }
}
document.getElementById("playId").onclick = function(){
    callFlashMethod();
};

 

  ④ 如何把 SWF 文件嵌入到 HTML 頁面中:

    使用 swfobject.js 可以將 swf 文件嵌入到 HTML 頁面中,參考資料 :http://www.cnblogs.com/Carpe-Diem/articles/2310831.html

  ⑤ 如何把 AMR(Audio) 和 Flash 播放AMR 兩種方式封裝起來:

    有了上面的鋪墊,輕而易舉的就可以封裝啦(主要看 isIE 為 true 的情況):

  

var RongIMLib;
(function (RongIMLib) {
    var RongIMVoice = (function () {
        function RongIMVoice() {
        }
        /**
        * 初始化聲音庫
        */
        RongIMVoice.init = function () {
            if (this.isIE) {
                var div = document.createElement("div");
                div.setAttribute("id", "flashContent");
                document.body.appendChild(div);
                var script = document.createElement("script");
                script.src = "http://cdn.ronghub.com/swfobject-2.0.0.min.js";
                var header = document.getElementsByTagName("head")[0];
                header.appendChild(script);
                setTimeout(function () {
                    var swfVersionStr = "11.4.0";
                    var flashvars = {};
                    var params = {};
                    params.quality = "high";
                    params.bgcolor = "#ffffff";
                    params.allowScriptAccess = "always";
                    params.allowfullscreen = "true";
                    var attributes = {};
                    attributes.id = "player";
                    attributes.name = "player";
                    attributes.align = "middle";
                    swfobject.embedSWF("http://cdn.ronghub.com/player-2.0.2.swf", "flashContent", "1", "1", swfVersionStr, null, flashvars, params, attributes);
                }, 200);
            }
            else {
                var list = ["http://cdn.ronghub.com/pcmdata-2.0.0.min.js", "http://cdn.ronghub.com/libamr-2.0.1.min.js"];
                for (var i = 0, len = list.length; i < len; i++) {
                    var script = document.createElement("script");
                    script.src = list[i];
                    document.head.appendChild(script);
                }
            }
            this.isInit = true;
        };
        /**
        * 開始播放聲音
        * @param data {string} amr 格式的 base64 碼
        * @param duration {number} 播放大概時長 用 data.length / 1024
        */
        RongIMVoice.play = function (data, duration) {
            this.checkInit("play");
            var me = this;
            if (me.isIE) {
                me.thisMovie().doAction("init", data);
            }
            else {
                me.palyVoice(data);
                me.onCompleted(duration);
            }
        };
        /**
        * 停止播放聲音
        */
        RongIMVoice.stop = function () {
            this.checkInit("stop");
            var me = this;
            if (me.isIE) {
                me.thisMovie().doAction("stop");
            }
            else {
                if (me.element) {
                    me.element.stop();
                }
            }
        };
        /**
        * 播放聲音時調用的方法
        */
        RongIMVoice.onprogress = function () {
            this.checkInit("onprogress");
        };
        RongIMVoice.checkInit = function (postion) {
            if (!this.isInit) {
                throw new Error("RongIMVoice not initialized,postion:" + postion);
            }
        };
        RongIMVoice.thisMovie = function () {
            return eval("window['player']");
        };
        RongIMVoice.onCompleted = function (duration) {
            var me = this;
            var count = 0;
            var timer = setInterval(function () {
                count++;
                me.onprogress();
                if (count >= duration) {
                    clearInterval(timer);
                }
            }, 1000);
            if (me.isIE) {
                me.thisMovie().doAction("play");
            }
        };
        RongIMVoice.base64ToBlob = function (base64Data, type) {
            var mimeType;
            if (type) {
                mimeType = { type: type };
            }
            base64Data = base64Data.replace(/^(.*)[,]/, '');
            var sliceSize = 1024;
            var byteCharacters = atob(base64Data);
            var bytesLength = byteCharacters.length;
            var slicesCount = Math.ceil(bytesLength / sliceSize);
            var byteArrays = new Array(slicesCount);
            for (var sliceIndex = 0; sliceIndex < slicesCount; ++sliceIndex) {
                var begin = sliceIndex * sliceSize;
                var end = Math.min(begin + sliceSize, bytesLength);
                var bytes = new Array(end - begin);
                for (var offset = begin, i = 0; offset < end; ++i, ++offset) {
                    bytes[i] = byteCharacters[offset].charCodeAt(0);
                }
                byteArrays[sliceIndex] = new Uint8Array(bytes);
            }
            return new Blob(byteArrays, mimeType);
        };
        RongIMVoice.palyVoice = function (base64Data) {
            var reader = new FileReader(), blob = this.base64ToBlob(base64Data, "audio/amr"), me = this;
            reader.onload = function () {
                var samples = new AMR({
                    benchmark: true
                }).decode(reader.result);
                me.element = AMR.util.play(samples);
            };
            reader.readAsBinaryString(blob);
        };
        RongIMVoice.isIE = /Trident/.test(navigator.userAgent);
        RongIMVoice.isInit = false;
        return RongIMVoice;
    })();
    RongIMLib.RongIMVoice = RongIMVoice;
    //相容AMD CMD
    if ("function" === typeof require && "object" === typeof module && module && module.id && "object" === typeof exports && exports) {
        module.exports = RongIMVoice;
    }
    else if ("function" === typeof define && define.amd) {
        define("RongIMVoice", [], function () {
            return RongIMVoice;
        });
    }
})(RongIMLib || (RongIMLib = {}));

截止到這裡,Flash 播放 AMR 格式 base64 碼 就說完了,主要是說說思路,覺得demo地址,可以再“Web 播放聲音  — 介紹篇”下載。

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 說在前面,本教程是建立在項目已經成功在模擬器上運行的基礎上,如果你是還未配置好環境的新手,建議先從官網快速入門開始:官網英文版 、 中文版 ok, 切入正題,當你已經完成好環境配置,在模擬器上成功的運行了項目,看到了下圖的效果,這時你的一定想,是時候去手機上裝個逼了! 找到官方的教程,開始一步步跟著
  • LESS 是css的一種擴展,它的編輯器是基於node.js 的less.js,將less文件編譯成css文件(可壓縮)。 其中的概念: 變數:定義變數來代替某個值,只能編譯一次,本質是“常量”。例如: @color:#ffddee; body { background-color:@color;
  • <body> <p>a=10,b=11,m=a+b,求m的值</p> <!--用文字表達--> <p id="sum"></p> <button onclick="mysum()">提交</button> <!--按鈕里的onclick事件是調用函數里的條件,這樣點擊它時即可執行函數--> <scr
  • 本文概述了TypeScript中如何使用模塊以各種方式來組織代碼。我們將涵括內部和外部的模塊,並且討論他們在適合在何時使用和怎麼使用。我們也會學習一些如何使用外部模塊的高級技巧,並且解決一些當我們使用TypeScript的模塊時遇到的陷阱。 案例的基礎 接下來開始寫程式,我們將會在這裡寫上使用案例。
  • 在文章初識js中的閉包中講解了閉包的一些概念,但是對於初學者來說可能並不是特別的容易理解,我今天用兩個案例來解釋閉包可能會好理解一些,在講案例之前,我們需要瞭解一些閉包的概念。在看這篇文章之前,請先看上面的那篇文章,不然效果不會太好。 閉包的理解: 所謂的閉包就是可以創建一個獨立的環境,每個閉包裡面
  • 1.字元串類型即String類型 它的值為字元串:由數字,字母,下劃線組成的一串字元 S=“sdf”它就是一個字元串,字元串一般加上雙引號,不加雙引號一般認為是非字元串類型 2.數字類型,即Number類型 數字可以輸入十進位,十六進位,八進位 3.布爾類型即Boolean類型 值為true或者fa
  • 本文主要介紹 AMR(Aduio) 播放 AMR 格式 Base64碼 音頻。 1、必備資料 github AMR 開源庫 :https://github.com/jpemartins/amr.js 用心把這個項目看一遍,對於我下麵說的話,可以忽略啦,代碼是最好的文章,哈哈~~ 2、核心 JS 庫
  • 最近甚是苦悶,屬於邊學邊做,跳進了很多坑,別提有多慘了,不過結果還是不錯滴,縱觀前後,一句話足以概括 “痛並快樂著” ~~~ ok,我少說廢話,下麵來總結下 Web 播放聲音一些註意事項。 說到 Web 我第一件事想起的就是瀏覽器相容性,播放聲音當然也難逃苦海,需要註意以 Trident 為內核 (
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...