Some of the technologies and cloud service features used:

  • Tencent cloud small live, Tencent cloud documents

  • Larave Boardcasting, documentation links

Debugging tools:

  • OBS, for push flow testing, official website
  • VLC, user pull flow test, official website

An introduction to vod/Live protocol

HLS (M3U8) Can be used for live streaming http://xxx.liveplay.myqcloud.com/xxx.m3u8 support support
Video agreement use URL Address format PC browser Mobile browser
HLS (M3U8) Can be used for vod http://xxx.vod.myqcloud.com/xxx.m3u8 support support
FLV Can be used for live streaming http://xxx.liveplay.myqcloud.com/xxx.flv support Does not support
FLV Can be used for vod http://xxx.vod.myqcloud.com/xxx.flv support Does not support
RTMP Live streaming only rtmp://xxx.liveplay.myqcloud.com/live/xxx support Does not support
MP4 On-demand only http://xxx.vod.myqcloud.com/xxx.mp4 support support
  • The RTMP protocol is recommended for live broadcast on mobile devices. The performance is good. When the network status is normal, the delay of live broadcast is about 2 to 5 seconds

  • HLS protocol compatibility is good, can be used with web live, but performance is poor, the test has a delay of more than 5 seconds.

Tencent cloud small live domain name configuration

To configure:

  • Push the basin of
  • La basin of

Configure CNAME to parse the links provided by Tencent Cloud.

Generate the push stream address

The push stream address is usually used by the host to push the video stream data to the server.

Use Tencent cloud small live service, according to the official example to use.

Generating formula of push stream address:

rtmp://domain/live/StreamName? txSecret=Md5(key+StreamName+hex(time))&txTime=hex(time)Copy the code

Four parameters are required to generate:

  1. Cloud live key, Tencent cloud to
  2. StreamName = streamName; streamName = streamName; streamName = streamName; streamName = streamName;
  3. Push the river basin, such as: 69045. livepush.myqcloud.com
  4. End time, such as maximum live duration of one day, now().addDay().toDateTimeString();

PHP example:

/** * get the stream address * If the key and expiration time are not passed, the url without anti-theft is returned *@paramDomain domain name that you use to push streams * streamName unique streamName that you use to distinguish different stream addresses * key security key * time expiration time sample 2016-11-12 12:00:00 *@return String url
			*/
			function getPushUrl($domain, $streamName, $key = null, $time = null){
			      if($key && $time){
			            $txTime = strtoupper(base_convert(strtotime($time),10.16));
			            //txSecret = MD5( KEY + streamName + txTime )
			            $txSecret = md5($key.$streamName.$txTime);
			            $ext_str = "?".http_build_query(array(
			                  "txSecret"=> $txSecret,
			                  "txTime"=> $txTime
			            ));
			      }
			      return "rtmp://".$domain."/live/".$streamName . (isset($ext_str) ? $ext_str : "");
			}
			
			echo getPushUrl("123.test.com"."123456"."69e0daf7234b01f257a7adb9f807ae9f"."The 2016-09-11 20:08:07");
Copy the code

Java examples:

package com.test;
			
			import java.io.UnsupportedEncodingException;
			import java.security.MessageDigest;
			import java.security.NoSuchAlgorithmException;
			
			public class Test {
			
			      public static void main(String[] args) {
			            System.out.println(getSafeUrl("txrtmp"."11212122".1469762325L));
			      }
			
			      private static final char[] DIGITS_LOWER =
			            {'0'.'1'.'2'.'3'.'4'.'5'.'6'.'7'.'8'.'9'.'a'.'b'.'c'.'d'.'e'.'f'};
			
			      /* * KEY+ streamName + txTime */
			      private static String getSafeUrl(String key, String streamName, long txTime) {
			            String input = new StringBuilder().
			                              append(key).
			                              append(streamName).
			                              append(Long.toHexString(txTime).toUpperCase()).toString();
			
			            String txSecret = null;
			            try {
			                  MessageDigest messageDigest = MessageDigest.getInstance("MD5");
			                  txSecret  = byteArrayToHexString(
			                              messageDigest.digest(input.getBytes("UTF-8")));
			            } catch (NoSuchAlgorithmException e) {
			                  e.printStackTrace();
			            } catch (UnsupportedEncodingException e) {
			                  e.printStackTrace();
			            }
			
			            return txSecret == null ? "" :
			                              new StringBuilder().
			                              append("txSecret=").
			                              append(txSecret).
			                              append("&").
			                              append("txTime=").
			                              append(Long.toHexString(txTime).toUpperCase()).
			                              toString();
			      }
			
			      private static String byteArrayToHexString(byte[] data) {
			            char[] out = new char[data.length << 1];
			
			            for (int i = 0, j = 0; i < data.length; i++) {
			                  out[j++] = DIGITS_LOWER[(0xF0 & data[i]) >>> 4];
			                  out[j++] = DIGITS_LOWER[0x0F & data[i]];
			            }
			            return newString(out); }}Copy the code

Debug the push stream function using OBS

  • Server fill in Tencent push stream address.

  • Stream key fill in the string following live/ in the address generated by the example above.

Examples of streaming keys:

test? txSecret=592172b126b77b71dbda74b1edf9b5de&txTime=5E65167FCopy the code

Test whether the push flow is successful

Open VLC, use the shortcut key Command+n, and enter the push basin name + stream name.

Example:

https://xxx.com/live/test
Copy the code

If successful, you can double-click the address directly open, you can see your push stream screen

Barrage function

The server will broadcast the data related to the barrage to the current broadcast room, and the front end will use laravel-Echo package to monitor the data, and then render the data to the current broadcast room.

PHP code example:

public function commentLiveRoomResolver($root, array $args, $context, $info)
    {
        $user         = getUser();
        $live_room_id = Arr::get($args, 'live_room_id'.null);
        $message      = Arr::get($args, 'message'.null);

        event(new NewLiveRoomMessage($user->id, $live_room_id, $message));
        return $message;
    }
Copy the code

NewLiveRoomMessage code:


      

namespace App\Events\LiveRoom;

use App\LiveRoom;
use App\User;
use Illuminate\Broadcasting\Channel;
use Illuminate\Queue\SerializesModels;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;

class NewLiveRoomMessage
{
    use Dispatchable.InteractsWithSockets.SerializesModels;

    public $user;
    public $message;
    public $liveRoom;

    /**
     * Create a new event instance.
     *
     * @param$userId Audience ID *@param$liveRoomId Studio ID *@param$message Barrage content */
    public function __construct($userId,$liveRoomId,$message)
    {
        $this->user = User::find($userId);
        $this->liveRoom = LiveRoom::find($liveRoomId);
        $this->message = $message;
    }

    public function broadcastWith(a):array
    {
        return [
            'user_id'= >$this->user->id,
            'user_name'= >$this->user->name,
            'user_avatar'= >$this->user->avatar_url,
            'live_room_id'= >$this->liveRoom->id,
            'message'= >$this->message,
        ];
    }

    public function broadcastOn(a): PresenceChannel
    {
        return new PresenceChannel('live_room.'.$this->liveRoom->id); }}Copy the code

If you need to record live broadcast barrage data into the database, then add the relevant code in the NewLiveRoomMessage listener.