liveStreaming API

hello @kaltura,

i am building an application that should be able to stream h.264 content via kaltua liveStreaming API.
unfortunately, i am a bit overwhelmed by the amount of options available when using the API.
from a very high-level point of view, i suspect the workflow to look similar as follows:

  1. get kaltura API session
  2. get token
  3. get entryId
  4. stream content to endpoint URL rtmp://[entryID].[p/b].kpublish.kaltura.com:1935/kLive/?t=[token]

which services/actions are needed to obtain a token+entryId?
for 3), i guess i should use liveStream/add, with

  • sourceType=MANUAL_LIVE_STREAM(or LIVE_STREAM?)
  • mediaType=VIDEO (ok for audio+video stream??)

for 2) - how to obtain the token

is this workflow somehow correct? what am i missing?

thx in advance
harald glanzer
austria

hello again,

i just realized that by using liveStream/add, sourceType=LIVE_STREAM, i already get the whole RTMP string, containing token + entryID.

i am now trying to feed this RTMP URL into gstreamer/rtmp sink, which does not work, my streaming client is not allowed to connect. using a network sniffer, i found the following error message:

“…Netstream Play Failed. Authentication failed. Partner exceeded max concurrent transocded live streams in entry[]…”

i am using a ‘free’ account at the moment for testing. do i need to upgrade my account, or is it possible to disable transcoding?

regards,
hari

Hi @hglanzer,

Indeed, the livestreaming API is somewhat complex as it has a lot of options.
I’ll do my best to simplify it for you.
First of all, I am assuming you are using our SaaS and not self hosting Kaltura on your own servers. If that is not so, please let me know as the answer in the event you are using Kaltura CE is different.

The first thing you need to do is call conversionprofile->list() in order to get your conversion profile ID. Here is a basic example, using cURL. Of course, the same can be done using any of our API clients and in fact, it is most recommended that you do use one of our client libs.

curl "-dclientTag=kalcli%3A17-10-02&filter%3AobjectType=KalturaConversionProfileFilter&filter%3AtypeEqual=2&ks=YOUR_KS_STRING_HERE&format=1" "http://www.kaltura.com/api_v3/service/conversionprofile/action/list"

typeEqual is set to 2 because that’s the value for the KalturaConversionProfileFilter::LIVE_STREAM enum.

You should get a result similar to the below:

{
	"objects": [
		{
			"id": PASSTHROUGH_CONVERSION_PROFILE_ID,
			"partnerId": YOUR_PARANER_ID,
			"status": 2,
			"type": 2,
			"name": "Passthrough",
			"systemName": "Passthrough_Live",
			"tags": "",
			"description": "Publish only the broadcasted stream",
			"createdAt": 1463589712,
			"flavorParamsIds": "32,36,37",
			"isDefault": false,
			"isPartnerDefault": false,
			"cropDimensions": {
				"left": -1,
				"top": -1,
				"width": -1,
				"height": -1,
				"objectType": "KalturaCropDimensions"
			},
			"clipStart": -1,
			"clipDuration": -1,
			"mediaParserType": 0,
			"calculateComplexity": true,
			"collectionTags": "mbr,ism",
			"detectGOP": 0,
			"objectType": "KalturaConversionProfile"
		},
		{
			"id": CLOUD_TRANSCODE_PROFILE_ID,
			"partnerId": YOUR_PARANER_ID,
			"status": 2,
			"type": 2,
			"name": "Cloud transcode",
			"systemName": "Default_Live",
			"tags": "",
			"description": "The default set of live renditions",
			"createdAt": 1463589712,
			"flavorParamsIds": "32,33,34,35",
			"isDefault": true,
			"isPartnerDefault": true,
			"cropDimensions": {
				"left": -1,
				"top": -1,
				"width": -1,
				"height": -1,
				"objectType": "KalturaCropDimensions"
			},
			"clipStart": -1,
			"clipDuration": -1,
			"mediaParserType": "0",
			"calculateComplexity": true,
			"collectionTags": "mbr,ism",
			"detectGOP": 0,
			"objectType": "KalturaConversionProfile"
		}
	],
	"totalCount": 2,
	"objectType": "KalturaConversionProfileListResponse"
}

So, in this example, two profiles are available: “Passthrough” and “Cloud transcode”, each with a unique ID [masked as PASSTHROUGH_CONVERSION_PROFILE_ID and CLOUD_TRANSCODE_PROFILE_ID in the above output].
The ID is unique per partner and so, you need to make this request to find yours.

Once you have that, you are ready to create a live entry. This is done by making a request to the service/livestream/action/add endpoint [livestream->add()].

The relevant params are:

# KalturaSourceType::LIVE_STREAM = 32
sourceType=32
liveStreamEntry:objectType=KalturaLiveStreamEntry
# KalturaMediaType::LIVE_STREAM_FLASH = 201
liveStreamEntry:mediaType=201
# the DVR window
liveStreamEntry:dvrWindow=120
# to get the conversion profile ID, call conversionprofile list filter:objectType=KalturaConversionProfileFilter filter:typeEqual=2
# the profile ID you got back from service/conversionprofile/action/list request:
liveStreamEntry:conversionProfileId=
liveStreamEntry:name=testme
# enable DVR, set to 0 if not required
liveStreamEntry:dvrStatus=1
# whether or not to create a VOD entry out of the stream:
# recordStatus=0 (DISABLED)  - disable recording
# recordStatus=1 (APPENDED) - append all streams to one VOD entry    
# recordStatus=2__(PER_SESSION) - create a new VOD entry per live stream session
liveStreamEntry:recordStatus=2
# optional entry description
liveStreamEntry:description=

For example, here is a full cURL request [KS is masked, of course]:

curl "-dclientTag=kalcli%3A17-10-02&liveStreamEntry%3AobjectType=KalturaLiveStreamEntry&liveStreamEntry%3AsourceType=32&liveStreamEntry%3AmediaType=201&liveStreamEntry%3AdvrWindow=120&liveStreamEntry%3AconversionProfileId=7561812&liveStreamEntry%3Aname=testme&liveStreamEntry%3AdvrStatus=1&liveStreamEntry%3ArecordStatus=2&ks=YOUR_KS_STRING_HERE" "http://www.kaltura.com/api_v3/service/livestream/action/add"

This request will return a KalturaLiveStreamEntry object which includes the following members:

        primaryBroadcastingUrl  rtmp://$ENTRY_ID.p.kpublish.kaltura.com:1935/kLive?t=$STREAM_PASSWD
        secondaryBroadcastingUrl        rtmp://$ENTRY_ID.b.kpublish.kaltura.com:1935/kLive?t=$STREAM_PASSWD
        primaryRtspBroadcastingUrl      rtsp://$ENTRY_ID.p.s.kpublish.kaltura.com:554/kLive/$ENTRY_ID_%i?t=$STREAM_PASSWD
        secondaryRtspBroadcastingUrl    rtsp://$ENTRY_ID.b.s.kpublish.kaltura.com:554/kLive/$ENTRY_ID_%i?t=$STREAM_PASSWD
        streamName      $ENTRY_ID_%i
        streamPassword  $STREAM_PASSWD

You can then use primaryBroadcastingUrl or primaryRtspBroadcastingUrl [depending on whether you want to use RTMP or RTSP] and $ENTRY_ID_%i as the stream name.

For example, when using the ffmpeg CLI binary to stream over RTMP, your command would be:

$ ffmpeg -re -i /path/to/some.mp4 -c:v copy -c:a libmp3lame -f flv -rtmp_live 1 \ 
rtmp://$ENTRY_ID.p.kpublish.kaltura.com:1935/kLive?t=$STREAM_PASSWD/$ENTRY_ID_1

Hi @hglanzer,

See my rather elaborate explanation which also includes a simple ffmpeg CLI command to test the streaming over RTMP.
Live streaming is not available for trial accounts, if you’re interested in live streaming, perhaps Kaltura VPaaS would interest you:
https://vpaas.kaltura.com/pricing.html

Alternatively, you can contact out sales team for information about the different pricing plans.

thx a lot, jess! i do not see this error message anymore, but the stream setup fails anyway (i see a RTMP publish, followed by a RTMP unpublish) - but i guess this is because of the trial account…

i am already waiting for a ‘real’ account for testing our implementation, provided by one of
our partner companies.

thx again for your fast & competent answer!
hari

hi again,

i got the login data from my customer - the url has the form https://api.kaltura.COMPANY-NAME.net, i.e. this does not look like SasS instance to me. i also do not get a ‘Passthrough’ conversion profile object (which i got when i used my ‘official’ kaltura trial account).

therefor - how does the process of retrieving an rtmp-endpoint-url differ for a self-hosted kaltura instance? is there any possibility to debug on the kaltura server why the streaming itself (via gstreamer) fails? again, with wireshark, i only see ‘publish/unpublish’ rtmp messages.

thx in advance!
hari

Hi @hglanzer,

As I said in my original reply, for Kaltura CE, things work differently. Since Wowza is neither FOSS nor free, Kaltura CE is shipped with the Nginx RTMP module which provides the live streaming over RTMP functionality.

First, you should check whether your customer is using the Kaltura Community Edition [CE] or Kaltura OnPrem [the commercial self hosted version]. If they are using CE, make sure the use a version that includes Kaltura Nginx and the RTMP module, this has been introduced in the 12.4.0 release, if they are using OnPrem, their deployment is managed by our professional services and they should speak to our support team about their live streaming options.

Assuming CE, you can read about how it works here:


And also here:

You can still create an entry using the API, you just need to set:

sourceType=30 //MANUAL_LIVE_STREAM
hlsStreamUrl=http://$YOUR_NGINX_HOST:$NGINX_PORT/hlsme/$DESIRED_STREAM_NAME.m3u8

Same as in the manual live entry creation instructions in the post I referenced above.

hi again, jess!

in the end it turned out that the customer is using self hosted kaltura with ‘On Premise’ edition.
how does setting up the livestream differ, compared to SaaS setup?

thx, again!
hari / austria

Hi @hglanzer,

Essentially, it’s the same mechanism as in SaaS but OnPrem setups vary and there’s also the matter of which version of it is being used. Since the OnPrem ENVs are managed by our professional services team, please have your customer contact our support team for further checking.

Thanks,

Hi jess,

my contact responsible for the customers ‘on-premise’ setup setup a livestream entry and provided me a rtmp link of the form

rtmp://live1.kaltura.xxxxx.net:1935/kLive/?p=201&e=0_heoi78ld&i=0&t=660be99b

there are no IP restrictions for this entry whatsoever. using your ffmpeg example together with this url fails anyway (as a similar gstreamer pipeline fails):

ffmpeg -re -i /path/to/some.mp4 -c:v copy -c:a libmp3lame -f flv -rtmp_live 1 rtmp://live1.kaltura.xxxxx.net:1935/kLive/?p=201&e=0_heoi78ld&i=0&t=660be99b

on network level, it looks like this:

  • client sends handshake C0+C1, ACK by server
  • server sends handshake S0+S1+S2, ACK by client
  • client sends connect(’/kLive/?p=201&e=0_heoi78ld&i=0&t=660be99b’), ACK by server
  • server sends _result(‘Netconnection.connect.success’), ACK by client
  • client sends releaseStream(’’) + FCPublish(’’) + createStream(), ACKs by server
  • server sends onFCPublish() + _result(), ACK by client
  • clients sends publish(’’)
  • server sends ‘Stream Begin’
  • servers sends TCP FIN, ACK = closes tcp connection <----------------------------********* --------------------
  • clients sends FCUnpublish() + deleteStream()

do you have any idead what is wrong here on protocol level? are there any possibilities to debug this stuff on the rtmp server side?

regards
harald glanzer

Hi @hglanzer.

Like I said in my previous reply:

Since the OnPrem ENVs are managed by our professional services team, please have your customer contact our support team for further checking.

Thanks,