騰訊云視頻接入初探

今日來公司的項目要求接入視頻,如是根據(jù)需求對網(wǎng)易云視頻袒炉,anychat旁理,騰訊云視頻進行了技術(shù)調(diào)研,因為基于響應(yīng)時間我磁,降噪等諸多效果的測試孽文,考慮,最終選擇了騰訊云視頻夺艰。因為騰訊云視頻剛剛推出不久芋哭,demo,文檔寫的不是太集中郁副,故在集成時出現(xiàn)多個坑】簦現(xiàn)對集成步驟做一下簡單歸納:

1.集成播放列表:

直播播放列表需要開通查詢統(tǒng)計信息(Beta)

該接口的相關(guān)文檔地址:https://www.qcloud.com/document/product/267/6110
這個接口需要提交工單才會開通霞势,默認是不開通的烹植。
開通后會產(chǎn)生appid和推流鑒權(quán)key (這個東西會在生成sign時使用,sign生成的規(guī)則是推流鑒權(quán)key直接拼接過期時間)

 String playUrl ="http://statcgi.video.qcloud.com/common_access?"+
            "cmd=1251175924&interface=Get_LiveStat"+
                    "&Param.n.page_no=1"+"&Param.n.page_size=20"+
                    "&t="+time+"&sign="+signValue;

cmd后面需要根據(jù)你自己的需要更換成自己的appid愕贡,我的核心代碼如下:
sign是推流鑒權(quán)key直接拼接過期時間進行md5生成:

md5工具類:

public class MD5Utils {
      static String MD5(String sourceStr) {
            String result = "";
            try {
                MessageDigest md = MessageDigest.getInstance("MD5");
                md.update(sourceStr.getBytes());
                byte b[] = md.digest();
                int i;
                StringBuffer buf = new StringBuffer("");
                for (int offset = 0; offset < b.length; offset++) {
                    i = b[offset];
                    if (i < 0)
                        i += 256;
                    if (i < 16)
                        buf.append("0");
                    buf.append(Integer.toHexString(i));
                }
                result = buf.toString();
                System.out.println("MD5(" + sourceStr + ",32) = " + result);
                System.out.println("MD5(" + sourceStr + ",16) = " + buf.toString().substring(8, 24));
            } catch (NoSuchAlgorithmException e) {
                System.out.println(e);
            }
            return result;
        }

}

過期時間戳轉(zhuǎn)化工具類:

public class TimeUtils {
//日期轉(zhuǎn)化為時間戳
     public static String dateToStamp(String s) throws Exception{
            String res;
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            Date date = simpleDateFormat.parse(s);
            long ts = (date.getTime()+300000)/1000;
            res = String.valueOf(ts);
            return res;
        }
     public static String stampToDate(String s){
            String res;
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            long lt = new Long(s);
            Date date = new Date(lt);
            res = simpleDateFormat.format(date);
            return res;
        }
}

查詢時間列表的核心邏輯:

    public static void main(String[] args) throws Exception {
        OkHttpClient client = new OkHttpClient();
       SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
          String time="";
        try {
            //獲取當前日期的時間戳
            time = TimeUtils.dateToStamp(sdf.format(new Date()));
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
           System.out.println(time);
             //推流鑒權(quán)key
            String key="7407d5829e270dd92661ffcf06169bcf";
            String signValue=MD5Utils.MD5(key+time);
            String playUrl ="http://statcgi.video.qcloud.com/common_access?"+
            "cmd=1251175924&interface=Get_LiveStat"+
                    "&Param.n.page_no=1"+"&Param.n.page_size=20"+
                    "&t="+time+"&sign="+signValue;
            System.out.println(playUrl);
        Request request = new Request.Builder().url(playUrl).build();
        Response response = client.newCall(request).execute();
        
        if (response.isSuccessful()) {
            System.out.println(response.body().string());
            
        } else {
            throw new IOException("Unexpected code " + response);
        }

獲取成功會如下顯示:

{"errmsg":"has no stream is living","message":"has no stream is living","output":null,"ret":0,"retcode":0}

如果有推流的話是:

{"errmsg":"","message":"","output":{"stream_count":1,"stream_info":[{"bandwidth":0.0,"client_ip":"125.46.216.125","flr":1.0,"fps":0,"online":0,"server_ip":"123.138.162.79","speed":0,"stream_name":"8818_b262bb2709","time":"2017-04-13 11:04:13"}],"total_bandwidth":0.0,"total_online":0},"ret":0,"retcode":0}

返回的是json這個由你自己的業(yè)務(wù)需求定

2.登錄用戶體系:

騰訊提供了兩種賬戶體系事秀,一種是托管的浓恶,一種是獨立的省核,托管的是需要注冊登錄騰訊tls體系豌熄,賬戶管理交由騰訊,獨立的就是不對現(xiàn)有用戶體系有影響憨琳,而是在需要調(diào)用騰訊的時候诫钓,去到騰訊上驗證一下,就像融云的token一樣篙螟。

2.1托管體系注冊

android:


accountHelper.TLSStrAccReg("xtfgq", "12345678", new TLSStrAccRegListener() {
            @Override
            public void OnStrAccRegSuccess(TLSUserInfo tlsUserInfo) {
//                tlsUserInfo.

                Log.e("vv","111");
            }

            @Override
            public void OnStrAccRegFail(TLSErrInfo tlsErrInfo) {
                Log.e("vv","222");
            }

            @Override
            public void OnStrAccRegTimeout(TLSErrInfo tlsErrInfo) {
                Log.e("vv","333");
            }
        });

需要在oncreate中完成初始化菌湃,這里面的appid與前面的不同,(特別注意)遍略,這個是開通騰訊云云通信里面的那個千萬不要搞錯惧所。

 accountHelper=TLSAccountHelper.getInstance().init(SettingActivity.this,1251175924,12001,"1.0.1");

托管登錄:

  loginHelper = TLSLoginHelper.getInstance()
                .init(getApplicationContext(), 11270, 12001, "1.0.1");
        loginHelper.TLSPwdLogin("用戶帳號", "用戶密碼".getBytes(), new TLSPwdLoginListener(){
            @Override
            public void OnPwdLoginSuccess(TLSUserInfo tlsUserInfo) {
  final TIMUser user = new TIMUser();
                user.setIdentifier("用戶帳號");
                user.setAccountType("12001");
                user.setAppIdAt3rd(String.valueOf(Constants.sdkAppId));
                TIMManager.getInstance().login(
                        Constants.sdkAppId,                   //sdkAppId骤坐,由騰訊分配
                        user,
                        loginHelper.getUserSig("用戶帳號"),                    //用戶帳號簽名,由私鑰加密獲得下愈,具體請參考文檔
                        new TIMCallBack() {//回調(diào)接口

                            @Override
                            public void onSuccess() {//登錄成功
                                Log.e("vvv","succuss");
                            //根據(jù)邏輯跳到不同界面
                            }

                            @Override
                            public void onError(int code, String desc) {//登錄失敗

                                //錯誤碼code和錯誤描述desc纽绍,可用于定位請求失敗原因
                                //錯誤碼code含義請參見錯誤碼表
                                Log.e("eer","eeror");

                            }
                        });

            }

            @Override
            public void OnPwdLoginReaskImgcodeSuccess(byte[] bytes) {

            }

            @Override
            public void OnPwdLoginNeedImgcode(byte[] bytes, TLSErrInfo tlsErrInfo) {

            }

            @Override
            public void OnPwdLoginFail(TLSErrInfo tlsErrInfo) {

            }

            @Override
            public void OnPwdLoginTimeout(TLSErrInfo tlsErrInfo) {

            }
        });

2.2 獨立模式,即usersinger需從自己的服務(wù)器獲得势似,可參考usersinger生成文檔:https://www.qcloud.com/document/product/269/1510拌夏。

客戶端不需要像剛才那樣先登陸tls,然后在成功回調(diào)里調(diào)用 TIMManager.getInstance().login履因,而是直接從自己的服務(wù)取得usersinger障簿,
代碼如下:

 final TIMUser user = new TIMUser();
                        user.setIdentifier(userid);
                        user.setAccountType("12001");
                        user.setAppIdAt3rd(String.valueOf(Constants.sdkAppId));
                        TIMManager.getInstance().login(
                                Constants.sdkAppId,                   //sdkAppId,由騰訊分配
                                user,
                               sig,                    //用戶帳號簽名搓逾,由私鑰加密獲得卷谈,具體請參考文檔
                                new TIMCallBack() {//回調(diào)接口

                                    @Override
                                    public void onSuccess() {//登錄成功
                                        Log.e("vvv","succuss");
                                    
                                    

                                    }

                                    @Override
                                    public void onError(int code, String desc) {//登錄失敗

                                        //錯誤碼code和錯誤描述desc杯拐,可用于定位請求失敗原因
                                        //錯誤碼code含義請參見錯誤碼表
                                        Log.e("eer","eeror");

                                    }
                                });

最后霞篡,不管哪中模式,都需要調(diào)用修改昵稱的騰訊接口端逼,否則會出現(xiàn)發(fā)彈幕上用戶名變成數(shù)字方面的問題朗兵。

 public void setMyNickName(String nickName){
        TIMFriendshipManager.getInstance().setNickName(nickName, new TIMCallBack() {
            @Override
            public void onError(int i, String s) {

            }

            @Override
            public void onSuccess() {

            }
        });
    }

3.加入聊天室:

 private void joinIMChatRoom(final String chatRoomId) {

        mGroupConversation = TIMManager.getInstance().getConversation(TIMConversationType.Group, chatRoomId);

        TIMGroupManager.getInstance().applyJoinGroup(chatRoomId, Constants.APPLY_CHATROOM + chatRoomId, new TIMCallBack() {
            @Override
            public void onError(int i, String s) {
                //已經(jīng)在是成員了
                if (i == Constants.IS_ALREADY_MEMBER) {

                    initTIMListener(chatRoomId);

                }
            }

            @Override
            public void onSuccess() {

                initTIMListener(chatRoomId);
            }
        });

    }

消息監(jiān)聽:

  public void initTIMListener(String chatRoomId) {
        mGroupConversation = TIMManager.getInstance().getConversation(TIMConversationType.Group, chatRoomId);
        TIMManager.getInstance().addMessageListener(msgListener);

    }
 /**
     * 群消息回調(diào)
     */
    private TIMMessageListener msgListener = new TIMMessageListener() {
        @Override
        public boolean onNewMessages(List<TIMMessage> list) {
            //SxbLog.d(TAG, "onNewMessages readMessage " + list.size());
            //解析TIM推送消息
            parseIMMessage(list);
            return false;
        }
    };
 /**
     * 解析消息回調(diào)
     *
     * @param list 消息列表
     */
    private void parseIMMessage(List<TIMMessage> list) {
        List<TIMMessage> tlist = list;

        if (tlist.size() > 0) {
            if (mGroupConversation != null)
                mGroupConversation.setReadMessage(tlist.get(0));
        }


        for (int i = tlist.size() - 1; i >= 0; i--) {
            TIMMessage currMsg = tlist.get(i);
            for (int j = 0; j < currMsg.getElementCount(); j++) {
                if (currMsg.getElement(j) == null)
                    continue;
                TIMElem elem = currMsg.getElement(j);
                TIMElemType type = elem.getType();

                //系統(tǒng)消息
                if (type == TIMElemType.GroupSystem) {
                    if (TIMGroupSystemElemType.TIM_GROUP_SYSTEM_DELETE_GROUP_TYPE == ((TIMGroupSystemElem) elem).getSubtype()) {

                    }


                }

                //最后處理文本消息
                if (type == TIMElemType.Text) {
                    if (currMsg.isSelf()) {
                        handleTextMessage(elem, name);
                    } else {
                        TIMUserProfile sendUser = currMsg.getSenderProfile();
                       String nick="";
                        if(sendUser!=null){
                            nick=sendUser.getNickName();
                        }else{
                            nick=currMsg.getSender();
                        }
                        handleTextMessage(elem,nick);
                    }
                }
            }
        }
    }

發(fā)送消息:

 mGroupConversation = TIMManager.getInstance().getConversation(TIMConversationType.Group, groupId);

        mGroupConversation.sendMessage(msg, new TIMValueCallBack<TIMMessage>() {//發(fā)送消息回調(diào)
            @Override
            public void onError(int code, String desc) {//發(fā)送消息失敗
                //錯誤碼code和錯誤描述desc,可用于定位請求失敗原因
                //錯誤碼code含義請參見錯誤碼表
                if (code == 85) { //消息體太長
                    if (null != getActivity()) {
                        Toast.makeText(getActivity(), "輸入內(nèi)容太長", Toast.LENGTH_SHORT).show();
                    }
                } else if (code == 6011) {//群主不存在
                    if (null != getActivity()) {
                        Toast.makeText(getActivity(), "群主不存在", Toast.LENGTH_SHORT).show();
                    }
                }

            }

            @Override
            public void onSuccess(TIMMessage timMessage) {//發(fā)送消息成功
                mBoolRefreshLock=false;
                for (int j = 0; j < timMessage.getElementCount(); j++) {
                    TIMElem elem = (TIMElem) timMessage.getElement(0);
                    if (timMessage.isSelf()) {
                        handleTextMessage(elem, name);
                    } else {
                        TIMUserProfile sendUser = timMessage.getSenderProfile();
                        String name;
                        if (sendUser != null) {
                            name = sendUser.getNickName();
                        }
                        else {
                            name = timMessage.getSender();
                        }
                        //String sendId = timMessage.getSender();

                        handleTextMessage(elem,name);
                    }
                }
            }
        });
    }

處理消息文本:

  /**
     * 處理文本消息解析
     *
     * @param elem
     * @param name
     */
    private void handleTextMessage(TIMElem elem, String name) {
        TIMTextElem textElem = (TIMTextElem) elem;
        if (textElem.getText() != null) {
            refreshTextListView(name, textElem.getText(), Constants.TEXT_TYPE);
        }

    }
 /**
     * 消息刷新顯示
     *
     * @param name    發(fā)送者
     * @param context 內(nèi)容
     * @param type    類型 (上線線消息和 聊天消息)
     */
    public void refreshTextListView(String name, String context, int type) {
        ChatEntity entity = new ChatEntity();
        entity.setSenderName(name);
        entity.setContext(context);
        entity.setType(type);
        notifyRefreshListView(entity);
        mListViewMsgItems.setVisibility(View.VISIBLE);
        if (mListViewMsgItems.getCount() > 1) {
            if (true)
                mListViewMsgItems.setSelection(0);
            else
                mListViewMsgItems.setSelection(mListViewMsgItems.getCount() - 1);
        }
    }

最后實現(xiàn)效果如圖:


2.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末顶滩,一起剝皮案震驚了整個濱河市余掖,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌礁鲁,老刑警劉巖盐欺,帶你破解...
    沈念sama閱讀 221,576評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異仅醇,居然都是意外死亡冗美,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,515評論 3 399
  • 文/潘曉璐 我一進店門析二,熙熙樓的掌柜王于貴愁眉苦臉地迎上來粉洼,“玉大人,你說我怎么就攤上這事叶摄∈羧停” “怎么了?”我有些...
    開封第一講書人閱讀 168,017評論 0 360
  • 文/不壞的土叔 我叫張陵蛤吓,是天一觀的道長宵喂。 經(jīng)常有香客問我,道長会傲,這世上最難降的妖魔是什么樊破? 我笑而不...
    開封第一講書人閱讀 59,626評論 1 296
  • 正文 為了忘掉前任愉棱,我火速辦了婚禮,結(jié)果婚禮上哲戚,老公的妹妹穿的比我還像新娘奔滑。我一直安慰自己,他們只是感情好顺少,可當我...
    茶點故事閱讀 68,625評論 6 397
  • 文/花漫 我一把揭開白布朋其。 她就那樣靜靜地躺著,像睡著了一般脆炎。 火紅的嫁衣襯著肌膚如雪梅猿。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,255評論 1 308
  • 那天秒裕,我揣著相機與錄音袱蚓,去河邊找鬼。 笑死几蜻,一個胖子當著我的面吹牛喇潘,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播梭稚,決...
    沈念sama閱讀 40,825評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼颖低,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了弧烤?” 一聲冷哼從身側(cè)響起忱屑,我...
    開封第一講書人閱讀 39,729評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎暇昂,沒想到半個月后莺戒,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,271評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡急波,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,363評論 3 340
  • 正文 我和宋清朗相戀三年从铲,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片幔崖。...
    茶點故事閱讀 40,498評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡食店,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出赏寇,到底是詐尸還是另有隱情吉嫩,我是刑警寧澤,帶...
    沈念sama閱讀 36,183評論 5 350
  • 正文 年R本政府宣布嗅定,位于F島的核電站自娩,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜忙迁,卻給世界環(huán)境...
    茶點故事閱讀 41,867評論 3 333
  • 文/蒙蒙 一脐彩、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧姊扔,春花似錦惠奸、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,338評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至嵌言,卻和暖如春嗅回,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背摧茴。 一陣腳步聲響...
    開封第一講書人閱讀 33,458評論 1 272
  • 我被黑心中介騙來泰國打工绵载, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人苛白。 一個月前我還...
    沈念sama閱讀 48,906評論 3 376
  • 正文 我出身青樓娃豹,卻偏偏與公主長得像,于是被迫代替她去往敵國和親丸氛。 傳聞我的和親對象是個殘疾皇子培愁,可洞房花燭夜當晚...
    茶點故事閱讀 45,507評論 2 359

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,283評論 25 707
  • 點擊查看原文 Web SDK 開發(fā)手冊 SDK 概述 網(wǎng)易云信 SDK 為 Web 應(yīng)用提供一個完善的 IM 系統(tǒng)...
    layjoy閱讀 13,785評論 0 15
  • 社交紅利閱讀筆記 書名:社交紅利(修訂升級版) 作者:徐志斌 出版社:中信出版社 正文前筆記: 推薦序1摘要 社交...
    鳧水閱讀 8,954評論 4 26
  • 這個學期起初的時候?qū)σ恍〇|西有所了解過著摔,就跳過很多東西吧,把一些自己認為重要的做出筆記谍咆,看了昨天的那東西禾锤,截圖搞得...
    六六的建斌閱讀 1,067評論 0 1
  • 大家特別是一些經(jīng)常減肥的人看到這個標題的第一反應(yīng)可能是不相信。請你耐心的往下看摹察,看完你就會相信了恩掷。 藥方:運動并通...
    軒昂媽閱讀 343評論 0 2