1.0.11 • Published 3 years ago

@chenge/hjplayer v1.0.11

Weekly downloads
-
License
Apache-2.0
Repository
github
Last release
3 years ago

HJPlayer

English | 中文

This Library currently support play FLV steam video and HLS stream video(do not support decrypt) in browser environment; It relies on HTML5 video element and MediaSource Extensions BOM API. only with H264 codec and AAC codec;

Why we do this?

This spring we finish a new PC web project, It needs to play FLV stream video and HLS stream video stream in a browser page. First, we import flv.js and hls.js at the same time, flv.js plays FLV stream video, hls.js plays HLS stream video; It was certainly worked well, but the filesize of the javascript does not. After studying the flv.js and hls.js code, we find the same process of two libraries; They all have download, demuxer, remuxer, controller function, so we try to use the framework of flv.js to assemble the download, demuxer and remuxer function of hls.js library; It works!!!; The filesize is less than flv.js + hls.js, but it can do similar functions to play flv stream video and hls stream video; (not perfectly, still has some coincident codes, can be more smaller); Thanks to flv.jshls.js;

How do this libary work?

When played flv stream video, loader downloads the flv stream data, and send data to FLVCodec module, FLVCodec module use the data to generates ISO BMFF (MP4) fragments - InitSegment(ftyp + moov) and MediaSegment(moof + mdat), and then sends them to Video Element through Media Source Extensions API and URLS API; When played hls stream video, based on flv process, loader module will parse the m3u8 document first;

Feature

  1. play flv live stream and flv playback;
  2. play hls live stream and hls playback;
  3. Chrome, FireFox, Safari 10, IE11 and Edge worked well;

Installation

npm install hjplayer --save

build

npm install

npm run build

How to import

This library can import the way of ES6 Moudule

import HJPlayer from 'hjplayer'

or import through script src;

<script src="./dist/hjplayer.js">

Getting Started

flv

if (HJPlayer.isSupported()) {
    player = new HJPlayer({
        type: 'flv',
        url: 'http://xxx.xxx.com/xxxx.flv',
    }, {
        ...user config
    });
    player.attachMediaElement(videoElement);
    player.load();
    player.play();
}

HLS

if (HJPlayer.isSupported()) {
    player = new HJPlayer({
        type: 'm3u8',
        url: 'http://xxx.xxx.com/xxxx.m3u8',
    }, {
        ...user config
    });
    player.attachMediaElement(videoElement);
    player.load();
    player.play();
}

demo

demo

config

When init the player, it needs MediaConfig(@required) and userConfig(@optional) params;

MediaConfig

fieldtypeDescription
typestringmedia type, 'flv' or 'mp4' or 'm3u8'
isLive?booleanwhether the media is a live stream
cors?booleanIndicates whether to enable CORS for http fetching
withCredentials?booleanIndicates whether to do http fetching with cookies
hasAudio?booleanIndicates whether the stream has audio track
hasVideo?booleanIndicates whether the stream has video track
duration?numberIndicates total media duration, in milliseconds
filesize?numberIndicates total file size of media file, in bytes
url?stringIndicates media URL, can be starts with 'https(s)' or 'ws(s)' (WebSocket flv only)
segments?Array<MediaSegment>Optional field for multipart playback, see MediaSegment

MediaSegment

If segments field exists, transmuxer will treat this MediaDataSource as a multipart source.

In multipart mode, duration filesize url field in MediaDataSource structure will be ignored.

MediaSegment Object :

fieldtypeDescription
durationnumberRequired field, indicates segment duration in milliseconds
filesize?numberOptional field, indicates segment file size in bytes
urlstringRequired field, indicates segment file URL

segments demo

{
    type: 'flv',
    // Required
    "segments": [
        {
            "duration": 3333,  // in milliseconds
            "filesize": 4444,  // in bytes
            "url": "http://xxxx/segments-1.flv"
        },
        {
            "duration": 5555,
            "filesize": 6666,
            "url": "http://xxxx/segments-2.flv"
        },
        {
            "duration": 7777,
            "filesize": 8888,
            "url": "http://xxxx/segments-3.flv"
        }
        ...
    ]
}

userConfig

fieldtypedefaultDescription
enableWorker?booleanfalseEnable separated thread for transmuxing (unstable for now)
enableStashBuffer?booleantrueEnable IO stash buffer. Set to false if you need realtime (minimal latency) for live stream playback, but may stalled if there's network jittering.
FORCE_GLOBAL_TAG?booleanfalseenable to use global tag HJPLAYER when console
GLOBAL_TAGstringHJPLAYERdefault global tag
ENABLE_CALLBACKbooleanfalseenable logger callback
ENABLE_ERRORbooleantrueenable console.error
ENABLE_INFObooleanfalseenable console.info
ENABLE_WARNbooleanfalseenable console.warn
ENABLE_DEBUGbooleanfalseenable console.debug
stashInitialSize?number384KBIndicates IO stash buffer initial size. Default is 384KB. Indicate a suitable size can improve video load/seek time.
isLive?booleanfalseSame to isLive in MediaDataSource, ignored if has been set in MediaDataSource structure. flv only
lazyLoad?booleantrueAbort the http connection if there's enough data for playback
lazyLoadMaxDuration?number3 * 60Indicates how many seconds of data to be kept for lazyLoad.
lazyLoadRecoverDuration?number30Indicates the lazyLoad recover time boundary in seconds.
deferLoadAfterSourceOpen?booleantrueDo load after MediaSource sourceopen event triggered. On Chrome, tabs which be opened in background may not trigger sourceopen event until switched to that tab.
autoCleanupSourceBufferbooleanfalseDo auto cleanup for SourceBuffer
autoCleanupMaxBackwardDurationnumber3 * 60When backward buffer duration exceeded this value (in seconds), do auto cleanup for SourceBuffer
autoCleanupMinBackwardDurationnumber2 * 60Indicates the duration in seconds to reserve for backward buffer when doing auto cleanup.
fixAudioTimestampGapbooleantrueFill silent audio frames to avoid a/v unsync when detect large audio timestamp gap.
accurateSeek?booleanfalseAccurate seek to any frame, not limited to video IDR frame, but may a bit slower. Available on Chrome > 50, FireFox and Safari.
seekType?string'range''range' use range request to seek, or 'param' add params into url to indicate request range.
seekParamStart?string'bstart'Indicates seek start parameter name for seekType = 'param'
seekParamEnd?string'bend'Indicates seek end parameter name for seekType = 'param'
rangeLoadZeroStart?booleanfalseSend Range: bytes=0- for first time load if use Range seek
customSeekHandler?objectundefinedIndicates a custom seek handler
reuseRedirectedURL?booleanfalseReuse 301/302 redirected url for subsequence request like seek, reconnect, etc.
referrerPolicy?stringno-referrer-when-downgradeIndicates the Referrer Policy when using FetchStreamLoader
headers?objectundefinedIndicates additional headers that will be added to request
HLS config.
tsAutoLevelChoose?booleanfalsewhen play hls. whether auto choose the suitable bitrate level
maxFragLookUpTolerance?float0.25This tolerance factor is used during fragment lookup. Instead of checking whether buffered.end is located within start, end range, frag lookup will be done by checking within start-maxFragLookUpTolerance, end-maxFragLookUpTolerance range.
defaultAudioCodecundefinedundefinedIf audio codec is not signaled in variant manifest, or if only a stream manifest is provided, libraty tries to guess audio codec by parsing audio sampling rate in ADTS header. If sampling rate is less or equal than 22050 Hz, then libraty assumes it is HE-AAC, otherwise it assumes it is AAC-LC. This could result in bad guess, leading to audio decode error, ending up in media error. It is possible to hint default audiocodec to libraty by configuring this value as below:

Player methods

The info below is the methods and properties of Player, you can controll the player or get some useful info;

static methods

methodsresultDescription
HJPlayer.isSupported()booleanwhether the browser support this lib
HJPlayer.typeSupported()Objectreturn the media type of browser support
HJPlayer.HJPlayerDefaultConfigObjectthe default config of player

Instance methods

methodsresultDescription
on()voidbind callback for player events
off()voidcancel bind callback for player events
attachMediaElement()voidbind media element
detachMediaElement()voidremove the link of the media element with SourceBuffer
load()voidload the media stream
unload()voidunload the media stream
play()Promisethe player plays the video
pause()voidthe player pauses

Instance property

propertyresultDescription
typestringplayer type: 'MSEPlayer' or 'NativePlayer'
bufferedTimeRangesthe TimeRanges of the player
durationnumberthe duration of the media element
volumenumberthe volume of the video
currentTimecurrentTimethe currentTime of the video
mutedbooleanwhether the video is muted
mediaInfoObjectthe meida info (metadata)
statisticsInfoObjectthe statistics info of player stauts, such as dropframe, speed etc;

HJPlayer.Events

HJPlayer.Events, you can use the way Player.on(HJPlayer.Events.xxx, fn) to get the info of player when play, Player.off(HJPlayer.Events.xxx) cancel listener

EventDescription
ERRORAn error occurred by any cause during the playback
LOADING_COMPLETEThe input MediaDataSource has been completely buffered to end
RECOVERED_EARLY_EOFAn unexpected network EOF occurred during buffering but automatically recovered
MEDIA_INFOProvides technical information of the media like video/audio codec, bitrate, etc.
METADATA_ARRIVEDProvides metadata which FLV file(stream) can contain with an "onMetaData" marker.
SCRIPTDATA_ARRIVEDProvides scriptdata (OnCuePoint / OnTextData) which FLV file(stream) can contain.
STATISTICS_INFOProvides playback statistics information like dropped frames, current speed, etc.
GET_SEI_INFOit will returns the SEI info(Uint8Array) .
HJ_PLAYER_LOGit will returns a log contains a type: string and a info: string
MANIFEST_PARSEDyou can get the details of index.m3u8: Object

HJPlayer.ErrorTypes

when player is playing, it maybe happen something unexpected, you can use player.on(HJPlayer.Events.ERROR, () => {}) to get what happend, HJPlayer.ErrorTypes.xxx is the error type; you will also get a Object contain reason, it will tell you more details

ErrorDescription
NETWORK_ERRORErrors related to the network
MEDIA_ERRORErrors related to the media (format error, decode issue, etc)
OTHER_ERRORAny other unspecified error

HJPlayer.ErrorDetails

prefix with HJPlayer.ErrorDetails: HJPlayer.ErrorDetails.xxxx

ErrorDescription
NETWORK_EXCEPTIONRelated to any other issues with the network; contains a reason
NETWORK_STATUS_CODE_INVALIDRelated to an invalid HTTP status code, such as 403, 404, etc.
NETWORK_TIMEOUTRelated to timeout request issues
NETWORK_UNRECOVERABLE_EARLY_EOFRelated to unexpected network EOF which cannot be recovered
MEDIA_MSE_ERRORRelated to MediaSource's error such as decode issue
MEDIA_FORMAT_ERRORRelated to any invalid parameters in the media stream
MEDIA_FORMAT_UNSUPPORTEDThe input MediaDataSource format is not supported by flv.js
MEDIA_CODEC_UNSUPPORTEDThe media stream contains video/audio codec which is not supported

Licence

HJPlayer.js is released under Apache 2.0 License

super class

This player is extended flv.js and hls.js

How it works?

How does HJPlayer works