1. 程式人生 > >阿里雲直播、直播錄製和點播

阿里雲直播、直播錄製和點播

近來公司有個直播類的專案,讓我調研下阿里雲直播,花了3、4天調研結束後,做下筆記,一方面自己日後便於檢視,另一方面與大家做個交流,有說的不正確的。歡迎指正。

需求說明:本專案有三個媒體端,分別是app、微信和pc。下面分別講述下三個媒體端的場景。
- app端是給講師直播用的
- 微信端是給學員看直播用的
- pc端是給管理員用的

下面介紹下阿里雲的直播使用:
1.在app端需要推流到阿里雲cdn,需要應用伺服器生成一個推流地址(有推流地址就能拼出拉流地址),且配置回撥監聽推流狀態.(如圖-1所示)
2.在微信端需要拉流地址(直播地址),需要從應用伺服器拿到拉流地址
3.配置直播錄播轉點播後,直播推流中斷三分鐘後,直播的視訊會被傳輸到點播,此時配置一個回撥地址(針對兩種情況進行回撥,如圖-2所示)
a.直播視訊已經被傳輸到點播(注意:此時已經得到videoid,但是視訊還在轉碼,還是無法播放)
b.傳輸到點播的視訊已經轉碼成功(此時可以播放視訊了)

圖-1

圖-2

package com.yx.tsing.course.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.yx.tsing.common.ConsHint;
import com.yx.tsing.common.Constant;
import com.yx.tsing.common.result.JsonPageResult;
import com.yx.tsing.common.result.JsonResult;
import
com.yx.tsing.course.domain.Course; import com.yx.tsing.course.service.CourseService; import com.yx.tsing.course.vo.*; import com.yx.tsing.utils.AliUtil; import com.yx.tsing.utils.MD5Util; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import
org.springframework.util.Assert; import org.springframework.web.bind.annotation.*; import tk.mybatis.mapper.entity.Example; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.text.MessageFormat; import java.util.Date; /** * create by zml on 2018/3/6 16:52 */ @RestController @RequestMapping("/course") public class CourseController { @Autowired private CourseService courseService; @Value("#{configProperties['live.appName']}") private String appName; @Value("#{configProperties['live.streamName']}") private String streamName; @Value("#{configProperties['live.vhost']}") private String vhost; @Value("#{configProperties['live.key']}") private String key; /** * 根據課程id拿到推流地址 * @param id * @throws Exception */ @RequestMapping(value = "/pushUrl") public JsonResult pushUrl(long id) { //傳入自定義引數,即傳入應用名稱和流名稱 // String AppName = "tsonline"; String StreamName = streamName +"_"+id; // String vhost = "live.ayxsoft.top"; //時間戳,有效時間 long time = System.currentTimeMillis() + 1800; //加密key,即直播後臺鑑權裡面自行設定 // String key = "qreVeWGNRC"; String strpush = "/" + appName + "/" + StreamName + "-" + time + "-0-0-" + key; // 裡面的直播推流中心伺服器域名、vhost域名可根據自身實際情況進行設定 String pushurl = "rtmp://video-center.alivecdn.com/" + appName + "/" + StreamName + "?vhost=" + vhost + "&auth_key=" + time + "-0-0-" + MD5Util.getMD5(strpush); // $strviewrtmp = "/$AppName/$StreamName-$time-0-0-$key"; // $strviewflv = "/$AppName/$StreamName.flv-$time-0-0-$key"; String strviewm3u8 = "/" + appName + "/" + StreamName + ".m3u8-" + time + "-0-0-" + key; String rtmpurl = "rtmp://" + vhost + "/" + appName + "/" + StreamName + "?auth_key=" + time + "-0-0-" + MD5Util.getMD5(strpush); // $flvurl = "http://live1.playzhan.com/$AppName/$StreamName.flv?auth_key=$time-0-0-".md5($strviewflv); String m3u8url = "http://" + vhost + "/" + appName + "/" + StreamName + ".m3u8?auth_key=" + time + "-0-0-" + MD5Util.getMD5(strviewm3u8); //列印推流地址,即通過鑑權簽名後的推流地址 System.out.println("推流地址== " + pushurl); //列印三種直播協議播放地址,即鑑權後的播放地址 System.out.println("播放地址rtmp PushUrlVo==" + rtmpurl); // echo $flvurl.'<br>'; System.out.println("播放地址m3u8url==" + m3u8url); //儲存播放地址到資料庫 courseService.playUrl(id,rtmpurl+";"+m3u8url); return new JsonResult(true,"success!",new PushUrlVo(pushurl)); } /** * 阿里雲直播平臺通知使用者當前域名推流狀態,例如推流成功或者斷流 * 中心推流回調(判斷課程是否在直播) * @throws Exception */ @RequestMapping(value = "/pushCallBack") public void pushCallBack(@RequestParam(value = "action",defaultValue = "",required = false) String action, @RequestParam(value = "app",defaultValue = "",required = false) String app, @RequestParam(value = "appname",defaultValue = "",required = false) String appname, @RequestParam(value = "id",defaultValue = "",required = false) String id, @RequestParam(value = "ip",defaultValue = "",required = false) String ip, @RequestParam(value = "node",defaultValue = "",required = false) String node) { System.out.println("action=="+action);//publish和publish_done System.out.println("app=="+app);// System.out.println("appname=="+appname);// System.out.println("id=="+id);// System.out.println("ip=="+ip);//171.13.130.227 System.out.println("node=="+node);//et2 long courseId = Long.valueOf(id.split("_")[1]); int type = 1; if("publish".equals(action)){ type = 2; }else if("publish_done".equals(action)){ type = 3; } courseService.setType(courseId ,type); } /** * 1.開啟直播錄製到點播後,當完成一個錄製週期或直播流結束時會生成一個點播視訊,此時阿里雲點播平臺會回撥此介面 * 2.視訊在點播平臺轉碼成功會回撥此介面 * 點播回撥 * @param request * @param response * @throws Exception */ @RequestMapping(value = "/playCallBack") public void callBack(HttpServletRequest request, HttpServletResponse response) throws Exception { String c_length=request.getHeader("content-length"); int c_i=Integer.parseInt(c_length); //解析阿里回撥伺服器的介面資料 String result = AliUtil.GetPostBody(request.getInputStream(), c_i); System.out.println("resultCallBack=="+result); JSONObject jsonObject = JSON.parseObject(result); String EventType = jsonObject.getString("EventType"); String Status = jsonObject.getString("Status"); if("AddLiveRecordVideoComplete".equals(EventType)){ //第一種情況,直播錄製轉點播成功 if("success".equals(Status)){ //儲存返回來的檔案資訊 //{"Status":"success","VideoId":"e5524b741330406c99e08698433dd387","StreamName":"StreamName_1","RecordStartTime":"2018-03-06T07:51:38Z","EventType":"AddLiveRecordVideoComplete","DomainName":"live.ayxsoft.top","RecordEndTime":"2018-03-06T07:53:47Z","UserId":1023641609718688,"EventTime":"2018-03-06T07:56:47Z","AppName":"tsonline"} String videoId = jsonObject.getString("VideoId"); String StreamName = jsonObject.getString("StreamName"); long courseId = Long.valueOf(StreamName.split("_")[1]); Course course = new Course(); course.setId(courseId); course.setType(3); course.setRecordPath(videoId); course.setUpdateTime(new Date()); courseService.updateByPrimaryKeySelective(course); //返回給點播伺服器 AliUtil.response(request, response, "{\"Status\":\"OK\"}", HttpServletResponse.SC_OK); } else { AliUtil.response(request, response, "{\"Status\":\"verdify not ok\"}", HttpServletResponse.SC_BAD_REQUEST); } }else if("TranscodeComplete".equals(EventType)){//第二種情況,視訊在點播平臺轉碼成功 if("success".equals(Status)){ //儲存返回來的檔案資訊d //{"VideoId": "43q9fjasjdflask","Status": "success","StreamInfos":[],"EventTime": "2017-03-20T07:49:17Z","EventType": "TranscodeComplete"} String videoId = jsonObject.getString("VideoId"); String status = jsonObject.getString("Status"); if("success".equals(status)){ Example example = new Example(Course.class); Example.Criteria criteria = example.createCriteria(); criteria.andEqualTo("recordPath",videoId); criteria.andEqualTo("type",3);//只考慮 直播錄播到點播轉碼成功 的情況 Course course = new Course(); course.setType(4); course.setUpdateTime(new Date()); courseService.updateByExampleSelective(course,example); } //返回給點播伺服器 AliUtil.response(request, response, "{\"Status\":\"OK\"}", HttpServletResponse.SC_OK); } else { AliUtil.response(request, response, "{\"Status\":\"verdify not ok\"}", HttpServletResponse.SC_BAD_REQUEST); } } } }

下面介紹下阿里雲的點播使用:
1.上傳,上傳時需要請求應用伺服器拿到上傳許可權和上傳地址
2.播放.播放有兩種方式,一種是用阿里雲播放器,另一種是使用自有、開源播放器

第一種,需要播放憑證(很安全,確保視訊不會被盜用)或者播放地址(可以開啟鑑權使生成的地址有時效性,相對安全);
第二種只需要播放地址即可