Overview
HTTP Live Streaming (HLS) is a technology to play streaming video via the HTTP protocol developed by Apple. An HLS video stream is encoded to H.264 and AAC and is played on any compatible device, browser or player.
Web Call Server converts to HLS video received from other supported sources of broadcasting such as web cameras and professional video capturing device, SIP calls and so on.
Supported platforms and browsers
Chrome | Firefox | Safari 11 | Edge | |
---|---|---|---|---|
Windows | + | + | + | |
Mac OS | + | + | + | |
Android | + | + | ||
iOS | + | + | + |
Supported codecs
- Video: H.264
- Audio: AAC
Operation flowchart
- The browser connects to the server via the Websocket protocol and sends the publish command.
- The browser captures the microphone and the camera and sends the WebRTC stream to the server.
- The second browser establishes a connection via HTTP.
- The second browser receives the HLS stream and plays this stream on the page.
Quick manual on testing
Publishing of a video stream on the server and playing it via HLS in a browser
1. For the test we use:
- WCS server;
- the Two Way Streaming web application to publish the stream
- the HLS Player Minimal web application to publish the stream
2. Open the Two Way Streaming web application. Click Connect, then Publish. Copy the identifier of the stream:
3. open the HLS Player Minimal web application. In the Stream field paste the identifier of the stream and click Play. The stream starts playing:
Call flow
Below is the call flow when using the HLS Player Minimal example to play a stream via HLS
1. Querying the server and playing.
var player = videojs('remoteVideo');
Configuring the HLS URL.
player.src({ src: $("#urlServer").val() + "/" + streamName + "/" + streamName + ".m3u8", type: "application/vnd.apple.mpegurl" });
Starting the playback.
player.play();
2. Receiving the HLS stream from the server
Streams which can be played as HLS
Every stream published to WCS server with certain name, can be played as HLS
http://wcs:8082/streamName/streamName.m3u8
A stream name can be set when publishing stream from browser or from RTMP кодировщика, or when capturing RTSP, RTMP or VOD stream using REST API
Since build 5.2.771, stream URI can be set for RTSP
http://wcs:8082/rtsp%3A%2F%2Frtspserver%2Flive.sdp/rtsp%3A%2F%2Frtspserver%2Flive.sdp.m3u8
RTMP source
http://wcs:8082/rtmp%3A%2F%2Frtmpserver%3A1935%2Flive%2Fstream/rtmp%3A%2F%2Frtmpserver%3A1935%2Flive%2Fstream.m3u8
or for VOD live translation from file
http://wcs:8082/vod-live%3A%2F%2Ffile.mp4/vod-live%3A%2F%2Ffile.mp4.m3u8
In this case a stream will be captured by source URI, and after publishing to server the stream will be played as HLS. Note that URI should be encoded, all the characters except latin letters and digits must be replaced with character code.
When HLS subscriber connects to CDN Edge, if a stream with certain name or URI is already published to some Origin server, the stream from CDN will be played as HLS for this subscriber. If there is no stream with such name or URI in CDN, Edge will try to capture stream locally to play as HLS.
HLS playback authentication using REST hook
A client authentication for HLS playback can be setup if necessary. To do this, the following parameter should be set in flashphoner.properties file
hls_auth_enabled=true
At client side, the parameter must be added to HLS URL to pass to WCS server a token obtained for example from backend server. The name of the parameter is defined with the following setting
client_acl_property_name=aclAuth
In this case, stream URL should be formed as follows
var src = $("#urlServer").val() + "/" + streamName + "/" + streamName + ".m3u8"; var token = $("#token").val(); if (token.length > 0) { src += "?aclAuth=" +token; }
REST hook /playHLS must be implemented on backend server in defaultApp application. WCS server will send query to backend with token received from client
URL:http://localhost:8081/apps/EchoApp/playHLS OBJECT: { "nodeId" : "NTk1tLorQ00llGbPJuFexrKceubGCR0k@192.168.1.5", "appKey" : "defaultApp", "sessionId" : "/192.168.1.100:59473/192.168.1.5:8445", "mediaSessionId" : "60709c5b-6950-40c3-8a3d-37ea0827ae32-727473703a2f2f73747238312e63726561636173742e636f6d2f6772616e646c696c6c6574762f6c6f77-HLS", "name" : "test", "mediaProvider" : "HLS", "custom" : { "token" : "12345789" } }
Backend server should return 200 OK if token is checked successfully, and 403 Forbidden if token is wrong. In its turn, client will receive either HLS stream or 401 Unauthorized.
The parameter
hls_auth_token_cache=10
defines token caching interval in seconds (10 seconds by default). /playHLS queries with certain token will not be sent to backend until the token is in cache i.e. either there is stream subscriber with this token or caching interval is not expired. If caching interval parameter is set to 0
hls_auth_token_cache=0
/playHLS queries are sent to backend on every HTTP GET request from client.
HLS authentication setting can be changed without server restart. In this case hls_auth_enabled
affects existing subscribers and hls_auth_token_cache
affects new subscribers only.
Custom backend application usage for HLS playback authentication
Since build 5.2.1008 it is possible to set backend application key in HLS URL, for example
httpы://wcs:8445/streamName/streamName.m3u8?appKey=customAppKey&aclAuth=1254789
In this case REST hook /playHLS will be sent to backend application with defined key (customAppKey in the example above).
Unauthorized access to HLS segments prevention
To decrease server load, authentication token and stream availability in CDN are checked on HLS playlist request. The following parameter is added since build 5.2.436 to protect separate HLS segments
hls_segment_name_suffix_randomizer_enabled=true
In this case, randomly generated suffix is added to every segment file name, for example
test16d2da4658f4374953a120f3c95bc715ea.ts
So, brute force iteration over segments is escaped.
Note that suffix is not added to preloader segments.
Adding cross-domain access control HTTP headers for HLS playback
By default, the followin access control headers are added to 200 OK response to HTTP GET request:
Access-Control-Allow-Origin: * Access-Control-Allow-Methods: GET Access-Control-Max-Age: 3000
If necessary, for example, if HLS content and HLS player page are in different domains, custom access control headers can be added using the following parameter in flashphoner.properties file:
hls_access_control_headers=Access-Control-Allow-Origin: *;Access-Control-Allow-Methods: GET, HEAD;Access-Control-Max-Age: 3000;Access-Control-Expose-Headers: Accept-Ranges, Content-Range, Content-Encoding, Content-Length
In this case, the headers listed in the parameter will be added to 200 OK response:
Mask support in ACAO header
Sometimes, for example, when load balancer AWS LB is used, it is necessary to set request origin address including port in ACAO header sent in response to GET request, for example
Access-Control-Allow-Origin: http://test.flashphoner.com:8081
However, origin address is not always known while configuring the server. Therefore, since build 5.2.755 mask support in ACAO header can be enabled
hls_acao_header_domain_mask=true
This feature is enabled by default. In this case, if '*' character is set in the following parameter
hls_access_control_headers=Access-Control-Allow-Origin: *
server returns ACAO header with full request origin address in response to GET request
Access-Control-Allow-Origin: http://lb.yourdomain.com:8081
This can be disabled if necessary
hls_acao_header_domain_mask=false
Using nginx as reverse proxy for HLS playback
In some cases nginx web server can be used as reverse proxy for HLS playback from WCS server. Usually, it may require if HTTP headers adding does not help to workaround cross domain request restrictions in some browsers.
For example, if browser requires HLS player page and HLS stream to be in the same domain your.domain and on the same port 443 (HTTPS), nginx should be set up as follows:
# HTTP requests are redirected from port 80 to 443 server { listen 80; server_name docs.flashphoner.com; return 301 https://$server_name$request_uri; } # Server listens HTTPS port 443 server { listen 443 ssl; ssl_certificate /etc/letsencrypt/live/your.domain/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/your.domain/privkey.pem; server_name your.domain; server_tokens off; client_max_body_size 500m; proxy_read_timeout 10m; root /usr/share/nginx/html; location / { } error_page 404 /404.html; location = /40x.html { } error_page 500 502 503 504 /50x.html; location = /50x.html { } # Example web applications will be available by URL https://your.domain/client2 location /client2/ { alias /usr/local/FlashphonerWebCallServer/client2/; } # HLS playlists and segments are proxying to your.domain on port 443. for example https://your.domain/test.m3u8 location ~* ^.+.(m3u8|ts)$ { proxy_pass https://localhost:8445; proxy_http_version 1.1; proxy_set_header Host $server_name:$server_port; proxy_set_header X-Forwarded-Host $http_host; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } }
It also may be useful to cache HLS stream. In this case nginx should be additionally set up as follow:
1. In http
section of /etc/nginx.conf settings file proxy cache parameters are set
proxy_cache_path /var/cache/nginx/proxy levels=1:2 keys_zone=proxy_cache:1024m max_size=2048m inactive=10d; proxy_cache_min_uses 1; proxy_ignore_headers X-Accel-Expires; proxy_ignore_headers Expires; proxy_ignore_headers Cache-Control;
2. In server
section of site settings file caching of HLS segments is set, playlist should not be cached:
location ~* ^.+.(ts)$ { proxy_pass https://localhost:8445; proxy_http_version 1.1; proxy_set_header Host $server_name:$server_port; proxy_set_header X-Forwarded-Host $http_host; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_cache proxy_cache; proxy_cache_key $host$uri$is_args$args; proxy_cache_valid 200 2m; } location ~* ^.+.(m3u8)$ { proxy_pass https://localhost:8445; proxy_http_version 1.1; proxy_set_header Host $server_name:$server_port; proxy_set_header X-Forwarded-Host $http_host; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_cache off; expires -1; }
Returning of static HTML pages on HLS port
Another way to workaround cross domain requests restrictions in browser is to return a static content, player page for example, on the same port that returns HLS content. To enable this feature, the following parameter should be set in flashphoner.properties file
hls_static_enabled=true
The player page should be in directory defined by the following parameter
hls_static_dir=client2/examples/demo/streaming/hls_static
In this case (by default) the path to the player page files is set relative to WCS installation directory. A full path may also be set, for example
hls_static_dir=/var/www/html/hls_static
If static content returning is enabled, browser will display the HLS player page by URL https://host:8445/hls-player.html. If this feature is disabled, server will return 404 Not found error by such URL.
Preloader for HLS stream playback
When first HLS subscribes connects to a stream on WCS server, especilally to CDN stream, it may take a time to split a stream to HLS segmets and to form a playlist. As a result, Safari browser on iOS devices may not be able to play HLS stream on the first attempt. To successfully play HLS stream in this case, the HLS preloader was added since build 5.2.371. The default preloader looks like this:
Since build 5.2.408 preloaders are divided by stream aspect ratio: 16:9, 4:3, 2:1
Default preloader segments are placed to /usr/local/FlashphonerWebCallserver/hls/.preloader
folder when server is started
tree /usr/local/FlashphonerWebCallServer/hls/.preloader /usr/local/FlashphonerWebCallServer/hls/.preloader ├── 16x9 │ ├── index0.ts │ ├── index10.ts │ ├── index11.ts │ ├── index12.ts │ ├── index13.ts │ ├── index14.ts │ ├── index15.ts │ ├── index16.ts │ ├── index17.ts │ ├── index18.ts │ ├── index19.ts │ ├── index1.ts │ ├── index2.ts │ ├── index3.ts │ ├── index4.ts │ ├── index5.ts │ ├── index6.ts │ ├── index7.ts │ ├── index8.ts │ └── index9.ts ├── 2x1 │ ├── index0.ts │ ├── index10.ts │ ├── index11.ts │ ├── index12.ts │ ├── index13.ts │ ├── index14.ts │ ├── index15.ts │ ├── index16.ts │ ├── index17.ts │ ├── index18.ts │ ├── index19.ts │ ├── index1.ts │ ├── index2.ts │ ├── index3.ts │ ├── index4.ts │ ├── index5.ts │ ├── index6.ts │ ├── index7.ts │ ├── index8.ts │ └── index9.ts └── 4x3 ├── index0.ts ├── index10.ts ├── index11.ts ├── index12.ts ├── index13.ts ├── index14.ts ├── index15.ts ├── index16.ts ├── index17.ts ├── index18.ts ├── index19.ts ├── index1.ts ├── index2.ts ├── index3.ts ├── index4.ts ├── index5.ts ├── index6.ts ├── index7.ts ├── index8.ts └── index9.ts
The minimal preloader segment duration is 2 seconds by default, and can be set in milliseconds with the following parameter
hls_preloader_time_min=2000
Disabling HLS preloader
HLS preloader can be disabled if necessary, this feature is available since build 5.2.396. To disable HLS preloader, the following parameter is used
hls_preloader_enabled=false
Custom preloader configuration
To replace the default preloader to thecustom one, do the following:
1. Choose video clip (logo for example) in three aspect ratios: 16:9, 4:3, 2:1
2. Encode video to H264, add audio track to the clip, set GOP and remove B-frames using ffmpeg
ffmpeg -i clip16x9.mp4 -f lavfi -i anullsrc=channel_layout=mono:sample_rate=44100 -c:v h264 -g 30 -bf 0 -shortest 16x9/preloader16x9.mp4 ffmpeg -i clip4x3.mp4 -f lavfi -i anullsrc=channel_layout=mono:sample_rate=44100 -c:v h264 -g 30 -bf 0 -shortest 4x3/preloader4x3.mp4 ffmpeg -i clip2x1.mp4 -f lavfi -i anullsrc=channel_layout=mono:sample_rate=44100 -c:v h264 -g 30 -bf 0 -shortest 2x1/preloader2x1.mp4
3. Download and install HLS tools from Apple site
4. Prepare custom preloader HLS segments with desired duration, for example 2 seconds
cd 16x9 mediafilesegmenter -t 2 -B index -start-segments-with-iframe preloader16x9.mp4 tar -cvzf preloader.tar.gz index*.ts
This step should be repeated for all aspect ratios.
5. Make a folder for custom preloader
mkdir /opt/custom_preloader mkdir /opt/custom_preloader/16x9 mkdir /opt/custom_preloader/4x3 mkdir /opt/custom_preloader/2x1
6. Unpack preloader segments from archive prepared on step 4
cd /opt/custom_preloader/16x9 tar -xvzf ~/preloader16x9.tar.gz
This step should also be repeated for all aspect ratios.
7. Set custom preloader folder and duration in server settings
hls_preloader_time_min=2000 hls_preloader_dir=/opt/custom_preloader
HLS subscription management using REST API
REST query should be HTTP/HTTPS POST request as follows:
- HTTP: http://test.flashphoner.com:8081/rest-api/hls/startup
- HTTPS: https://test.flashphoner.com:8444/rest-api/hls/startup
Where:
- test.flashphoner.com - WCS server address
- 8081 - WCS server standard REST / HTTP port
- 8444 - standard HTTPS port
- rest-api - mandatory URL part
- /hls/startup - REST method used
REST queries and response sates
REST query | Body example | Response example | Response state | Desctiption |
---|---|---|---|---|
/hls/startup | { "name":"test" } | 200 - OK 404 - Stream not found 500 - Internal error | Start HLS agent for the stream | |
/hls/find_all | { "test": { "handler": "com.flashphoner.server.client.handler.wcs4.WCS4Handler@74dbf27b", "state": "ACTIVE", "writer": "HLS-test", "streamStatus": "PLAYING", "writerStarted": "true" } } | 200 – OK 404 – Not found | Find all streams having HLS agents | |
/hls/terminate | { "name":"test" } | 200 – OK 404 – Not found | Stop or restart HLS agent for the stream |
Parameters
Parameter name | Description | Example |
---|---|---|
name | Stream published name | test |
Issues
1. If HLS agent for the stream is started by REST query /hls/startup, and there are no active HLS subscribers, agent will stop after the following timeout in seconds
hls_manager_provider_timeout=300
By default, the timeout is 5 minutes. Also it concerns HLS agents which are started automatically for streams published using the following parameter
hls_auto_start=true
2. If HLS agent for the stream is stopped by REST query /hls/terminate, and there are active HLS subscribers, this agent will be restarted. In this case, active HLS subscribers must reconnect to the stream.
HLS ABR support
Legacy HLS ABR implementation in builds 5.2.484 - 5.2.582
Since build 5.2.484 HLS ABR playlists support was added. This feature can be enabled with the following parameter
hls_master_playlist_enabled=true
Master playlist file name can be set using the following parameter
hls_manifest_file=index.m3u8
Browser should get master playlist by URL
https://wcs_address:8445/streamName/index.m3u8
Where
- wcs_address - WCS server address
- streamName - stream name
- index.m3u8 - master playlist file name
When master playlist is requested for the stream, server checks if streams are published according to transcoding profiles listed in cdn_profiles.yml file, for example:
profiles: -720p: video: height: 720 bitrate: 1000 codec: h264 -480p: video: height: 480 bitrate: 1000 codec: h264 -240p: video: height: 240 bitrate: 400 codec: h264
All the streams published by profiles on server, will be added to master playlist, for example:
#EXTM3U #EXT-X-STREAM-INF:BANDWIDTH=1000000,RESOLUTION=1280x720,CODECS="avc1.42e01f,mp4a.40.2" ../streamName-720p/streamName-720p.m3u8 #EXT-X-STREAM-INF:BANDWIDTH=1000000,RESOLUTION=852x480,CODECS="avc1.42e01f,mp4a.40.2" ../streamName-480p/streamName-480p.m3u8 #EXT-X-STREAM-INF:BANDWIDTH=400000,RESOLUTION=426x240,CODECS="avc1.42e01f,mp4a.40.2" ../streamName-240p/streamName-240p.m3u8 #EXT-X-STREAM-INF:BANDWIDTH=2500000,RESOLUTION=1280x720,CODECS="avc1.42e01f,mp4a.40.2" ../streamName/streamName.m3u8
Then browser switches between HLS streams listed in master playlist depending on channel bandwidth.
When browser requests master playlist for the certain stream, transcoded stream must already be published on server and must be cut to HLS segments
To provide HLS streams by profiles, the following should be done:
1. On a standalone server:
1.1. Periodically check if streams are transcoded to parameters set by profiles, and launch transcoding if necessary using REST API
curl -s -X POST -d "{\"uri\":\"transcoder://tcode_test-240p\",\"remoteStreamName\":\"test\",\"localStreamName\":\"test-240p\",\"encoder\":{\"width\":320,\"height\":240}}" http://localhost:8081/rest-api/transcoder/startup curl -s -X POST -d "{\"uri\":\"transcoder://tcode_test-480p\",\"remoteStreamName\":\"test\",\"localStreamName\":\"test-480p\",\"encoder\":{\"width\":640,\"height\":480}}" http://localhost:8081/rest-api/transcoder/startup curl -s -X POST -d "{\"uri\":\"transcoder://tcode_test-720p\",\"remoteStreamName\":\"test\",\"localStreamName\":\"test-720p\",\"encoder\":{\"width\":1280,\"height\":720}}" http://localhost:8081/rest-api/transcoder/startup
1.2. Periodically launch HLS cut for the streams, for example
curl -s -X POST -d "{\"name\":\"test\"}" http://localhost:8081/rest-api/hls/startup sleep 1 curl -s -X POST -d "{\"name\":\"test-240p\"}" http://localhost:8081/rest-api/hls/startup sleep 1 curl -s -X POST -d "{\"name\":\"test-480p\"}" http://localhost:8081/rest-api/hls/startup sleep 1 curl -s -X POST -d "{\"name\":\"test-720p\"}" http://localhost:8081/rest-api/hls/startup
2. On an Edge server in CDN periodically request HLS streams by transcoding profiles, for example
curl -s http://localhost:8082/test/test.m3u8 sleep 1 curl -s http://localhost:8082/test-240p/test-240p.m3u8 sleep 1 curl -s http://localhost:8082/test-480p/test-480p.m3u8 sleep 1 curl -s http://localhost:8082/test-720p/test-720p.m3u8 sleep 1
Actual HLS ABR implementation in build 5.2.585 and newer
Since build 5.2.585 HLS ABR implementation is significally changed. As usual, HLS ABR can be used in CDN only, but Edge server captures all the transcoded streams for ABR manifest stream variants within the same mediasession to syhchronize the stream variants. This requires to configure Tanscoder nodes and Edge nodes simultaneously, and adds some limits. Let's explore it below.
Transcoder node settings
To synchronize all the variants of the same stream, encoding should be aligned on Transcoder node
transcoder_align_encoders=true
Also, FPS filter should be enabled
video_filter_enable_fps=true video_filter_fps=25
All stream variants key frames (GOPs) should be synchronized. For example, we will send key frame every 2 seconds for 25 fps stream
video_filter_fps_gop_synchronization=50
HLS Edge node settings
HLS preloader and streams resizing should be disabled on HLS Edge node
hls_preloader_enabled=false hls_player_width=0 hls_player_height=0
The transcoding profiles should be set as follows in cdn_profiles.yml file
profiles: -240p: audio: codec : mpeg4-generic rate : 48000 video: height : 240 bitrate : 300 gop : 50 codec : h264 -480p: video: height : 480 bitrate : 600 gop : 50 codec : h264 -720p: video: height : 720 bitrate : 1000 gop : 50 codec : h264
Note that audio parameters can be set for the first profile only because those parameters should be identical for all the profiles, and will be applyed according to the first profile.
Then HLS ABR should be enabled
hls_abr_enabled=true
Usage
Client should request ABR manifest giving a stream name with a special suffix
https://server:8445/test_0-HLS-ABR-STREAM/test_0-HLS-ABR-STREAM.m3u8
The suffix can be set with the following parameter
hls_abr_stream_name_suffix=-HLS-ABR-STREAM
The playlist contains links to stream variants playlists, a client can switch between then
#EXTM3U #EXT-X-STREAM-INF:BANDWIDTH=614400,RESOLUTION=852x480,CODECS="avc1.42e01f,mp4a.40.2" -480p/-480p.m3u8 #EXT-X-STREAM-INF:BANDWIDTH=1024000,RESOLUTION=1278x720,CODECS="avc1.42e01f,mp4a.40.2" -720p/-720p.m3u8 #EXT-X-STREAM-INF:BANDWIDTH=307200,RESOLUTION=426x240,CODECS="avc1.42e01f,mp4a.40.2" -240p/-240p.m3u8
If stream name contains no suffix, HLS will be played without ABR support.
Transcoding to higher resolutions prevention
If stream transcoding to higher resolutions is disabled on HLS ABR Edge server
cdn_strict_transcoding_boundaries=true
then stream variants conforming to higher resolution profiles will not be cut for the stream, and will not be vailable to a player.
Known limits
1. HLS Edge can be used for HLS streaming only, client sessions of another kinds will not work.
2. Stream recording, snapshots, mixing, stream capturing from another server and other captured stream management functions will not work.
HLS segments storage
Using disk
By default, HLS segments are written to server hard drive to the /usr/local/FlashphonerWebCallServer/hls folder. Starting from build 5.2.687, the folder for saving segments can be changed using the following parameter
hls_dir=/usr/local/FlashphonerWebCallServer/hls
(Preloader folder is configured separately with parameter hls_preloader_dir.)
The number of stored segments corresponds to the specified playlist size, 10 by default
hls_list_size=10
The less segments number, the less playback latency. However subscribers with poor channel could request HLS segments which are already gone from playlist and disk if playlist is short. To fix it, since build 5.2.581 the certain number of segments can be stored on disk after they gone from playlist. This feature can be enabled by the following parameter
hls_hold_segments_before_delete=true
By default, 5 last segments will be stored
hls_hold_segments_size=5
For example, if playlist contains 3 segments
#EXTM3U #EXT-X-VERSION:8 #EXT-X-TARGETDURATION:11 #EXT-X-MEDIA-SEQUENCE:15 #EXT-X-DISCONTINUITY-SEQUENCE:1 #EXTINF:3.415, test_017.ts #EXTINF:10.417, test_018.ts #EXTINF:9.084, test_019.ts
3 current segments and 5 previous segments will be stored on disk
test_012.ts test_013.ts test_014.ts test_015.ts test_016.ts test_017.ts test_018.ts test_019.ts
Using memory
Under high load, for example on HLS streaming dedicated server, segments reading from hard drive to send them to subscribers can increase the latency. In this case, HLS segments storing in memory should be enabled
hls_store_segment_in_memory=true
Segments will be read from memory to send them to subscribers, and will also be written to hard drive for debugging purposes. Note this will require more Java heap memory.
Debug logs for HLS session
For an error report, debug logging can be enabled for HLS sessions using CLI
update node-setting --value true hls_enable_session_debug
Note that config flashphoner.properties will be overwritten after the command.
Known issues
1. Non-recoverable freeze of HLS stream played in iOS Safari through a CDN
Symptoms: one minute after publishing start image stops, sound continues to play
Solution:
b) enable transcoding on server using the following option in flashphoner.properties file
disable_streaming_proxy=true
b) if transcoding is undesirable, set the following option in flashphoner.properties file
hls_discontinuity_enabled=true
In this case, clicks are possible in audio, but video will not stop.
2. HLS segments writing stops when playing stream published in Firefox browser.
Symptoms: a few minutes after playback start HLS segments stop writing, in that case the stream directory in hls directory is not deleted, and messages in server log continue to appear
INFO HLSStreamManager - HLSStreamProviderKeepaliveThread-80 Remove hls channel
Publisher must publish stream again to recover.
Solution: use another browser to publish the stream which supposed to be played via HLS.
3. No video for the first subscriber when playing HLS in Safari on iOS 12.4
Symptoms: no video for the first subscriber when playing a stream as HLS in Safari on iOS 12.4, however video is played normally if there are other HLS-subscribers to the stream
Solution: set the minimum HLS playlist segments count not less than 2
hls_min_list_size=2
4. No video for any subscriber when playing RTMP stream as HLS in Safari on iOS 12.4 if the following parameter is set to
hls_auto_start=true
Symptoms: no video for any subscriber when playing RTMP stream as HLS in Safari on iOS 12.4
Soluition: use mono sound when a file with stereo sound track is published, for example, set the followint command line options for ffmpeg
-acodec aac -ac 1
5. If stream transcoded by CDN is played as HLS, and if stream aspect ratio is changed during transcoding, HLS preloader is shown by original stream aspect ratio
Symptoms: when stream transcoded is requested by setting profile name, test-640x480p for example, 16x9 preloader is shown if original stream is 1280x720
Solution: turn on aspect ratio preserving on Transcoder CDN nodes
video_transcoder_preserve_aspect_ratio=true
6. If the source stream contains B-fames, the picture can twitch in some players
Symptoms: a strong picture twitching while playing a stream via HLS, this may lokk like low FPS
Solution: update WCS to build 5.2.863, where the problem is solved