npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

pili

v1.5.5

Published

Pili Streaming Cloud Server-Side Library For NodeJS

Downloads

10

Readme

Pili Streaming Cloud server-side library for NodeJS

Features

  • Stream Create, Get, List
    • [x] hub.createStream()
    • [x] hub.getStream()
    • [x] hub.listStreams()
  • Stream operations else
    • [x] stream.toJSONString()
    • [x] stream.update()
    • [x] stream.disable()
    • [x] stream.enable()
    • [x] stream.status()
    • [x] stream.rtmpPublishUrl()
    • [x] stream.rtmpLiveUrls()
    • [x] stream.hlsLiveUrls()
    • [x] stream.httpFlvLiveUrls()
    • [x] stream.segments()
    • [x] stream.hlsPlaybackUrls()
    • [x] stream.saveAs()
    • [x] stream.snapshot()
    • [x] stream.delete()

Content

Installaion

// install latest version
npm install pili --save

Usage

Configuration

var Pili = require('pili');

var ACCESS_KEY  = 'QiniuAccessKey';
var SECRET_KEY  = 'QiniuSecretKey';

var HUB = 'PiliHubName'; // The Hub must be exists before use

// Change API host as necessary
//
// pili.qiniuapi.com as default
// pili-lte.qiniuapi.com is the latest RC version
//
// Pili.config.API_HOST = 'pili.qiniuapi.com'; // default

Hub

Instantiate a Pili Hub object

var credentials = new Pili.Credentials(ACCESS_KEY, SECRET_KEY);
var hub = new Pili.Hub(credentials, HUB);

Create a new Stream

var options = {
  title          : null,    // optional, auto-generated as default
  publishKey     : null,    // optional, auto-generated as default
  publishSecurity : "static" // optional, can be "dynamic" or "static", "dynamic" as default
};

hub.createStream(options, function(err, stream) {
  if (!err) {
      console.log(stream);
    // Log stream
    // {
    //     "id":"z1.coding.35d7zfabe3bv5723280200c5",
    //     "createdAt":"2015-08-22T03:43:55.247Z",
    //     "updatedAt":"2015-08-22T03:43:55.247Z",
    //     "title":"35d7zfabe3bv5723280200c5",
    //     "hub":"coding",
    //     "publishKey":"f054e65199703b14",
    //     "publishSecurity":"static",
    //     "disabled":false,
    //     "profiles":null,
    //     "hosts":
    //     {
    //         "publish":
    //         {
    //             "rtmp":"scv02k.publish.z1.pili.qiniup.com"
    //         },
    //         "live":
    //         {
    //             "http":"scv02k.live1-http.z1.pili.qiniucdn.com",
    //             "rtmp":"scv02k.live1-rtmp.z1.pili.qiniucdn.com"
    //         },
    //         "playback":
    //         {
    //             "http":"scv02k.playback1.z1.pili.qiniucdn.com"
    //         }
    //     }
    // }
  } else {
    // Log error
    console.log(err + 'error code: ' + err.errorCode + 'http code: ' err.httpCode);
  }
});

Get a Stream

var streamId = 'z1.coding.35d7zfabe3bv5723280200c5';  // required
hub.getStream(streamId, function(err, stream) {
    if (!err) {
        console.log(stream);
        // Log stream
        // {
        //     "id":"z1.coding.35d7zfabe3bv5723280200c5",
        //     "createdAt":"2015-08-22T03:43:55.247Z",
        //     "updatedAt":"2015-08-22T03:43:55.247Z",
        //     "title":"35d7zfabe3bv5723280200c5",
        //     "hub":"coding",
        //     "publishKey":"f054e65199703b14",
        //     "publishSecurity":"static",
        //     "disabled":false,
        //     "profiles":null,
        //     "hosts":
        //     {
        //         "publish":
        //         {
        //             "rtmp":"scv02k.publish.z1.pili.qiniup.com"
        //         },
        //         "live":
        //         {
        //             "http":"scv02k.live1-http.z1.pili.qiniucdn.com",
        //             "rtmp":"scv02k.live1-rtmp.z1.pili.qiniucdn.com"
        //         },
        //         "playback":
        //         {
        //             "http":"scv02k.playback1.z1.pili.qiniucdn.com"
        //         }
        //     }
        // }
    }
});

List Stream

var options = {
    marker : null,    // optional
    limit  : null,    // optional
    title  : null     // optional
};

hub.listStreams(options, function(err, marker, streams) {
  streams.forEach(function(stream) {
    console.log(stream);
    // Log stream
    // {
    //     "id":"z1.coding.35d7zfabe3bv5723280200c5",
    //     "createdAt":"2015-08-22T03:43:55.247Z",
    //     "updatedAt":"2015-08-22T03:43:55.247Z",
    //     "title":"35d7zfabe3bv5723280200c5",
    //     "hub":"coding",
    //     "publishKey":"f054e65199703b14",
    //     "publishSecurity":"dynamic",
    //     "disabled":false,
    //     "profiles":null,
    //     "hosts":
    //     {
    //         "publish":
    //         {
    //             "rtmp":"scv02k.publish.z1.pili.qiniup.com"
    //         },
    //         "live":
    //         {
    //             "http":"scv02k.live1-http.z1.pili.qiniucdn.com",
    //             "rtmp":"scv02k.live1-rtmp.z1.pili.qiniucdn.com"
    //         },
    //         "playback":
    //         {
    //             "http":"scv02k.playback1.z1.pili.qiniucdn.com"
    //         }
    //     }
    // }
  });
});

Stream

To JSON String

var result = stream.toJSONString();
console.log(result);
// {"id":"z1.coding.55d7f30ce3ba5723280000c5","createdAt":"2015-08-22T03:57:00.064Z","updatedAt":"2015-08-22T03:57:00.064Z","title":"55d7f30ce3ba5723280000c5","hub":"coding","publishKey":"131be2572c682413","publishSecurity":"dynamic","disabled":false,"profiles":null,"hosts":{"publish":{"rtmp":"scv02k.publish.z1.pili.qiniup.com"},"live":{"http":"scv02k.live1-http.z1.pili.qiniucdn.com","rtmp":"scv02k.live1-rtmp.z1.pili.qiniucdn.com"},"playback":{"http":"scv02k.playback1.z1.pili.qiniucdn.com"}}}

Update a Stream

var options = {
  publishKey     : 'new_secret_words',  // optional
  publishSecrity : 'static',            // optional, can be "dynamic" or "static"
  disabled       : false                // optional, can be "true" of "false"
};

stream.update(options, function(err, stream) {
    console.log(stream);
    // Log stream
    // {
    //     "id":"z1.coding.35d7zfabe3bv5723280200c5",
    //     "createdAt":"2015-08-22T03:43:55.247Z",
    //     "updatedAt":"2015-08-22T03:43:55.247Z",
    //     "title":"35d7zfabe3bv5723280200c5",
    //     "hub":"coding",
    //     "publishKey":"new_secret_words",
    //     "publishSecurity":"static",
    //     "disabled":false,
    //     "profiles":null,
    //     "hosts":
    //     {
    //         "publish":
    //         {
    //             "rtmp":"scv02k.publish.z1.pili.qiniup.com"
    //         },
    //         "live":
    //         {
    //             "http":"scv02k.live1-http.z1.pili.qiniucdn.com",
    //             "rtmp":"scv02k.live1-rtmp.z1.pili.qiniucdn.com"
    //         },
    //         "playback":
    //         {
    //             "http":"scv02k.playback1.z1.pili.qiniucdn.com"
    //         }
    //     }
    // }
});

Disable a Stream

stream.disable(function(err, stream) {
	console.log(stream.disabled);
	// true
});

Enable a Stream

stream.enable(function(err, stream) {
	console.log(stream.disabled);
	// false
});

Get Stream status

stream.status(function(err, status) {
    if (!err) {
        console.log(status);
        // Log stream status
        // {
        //     "addr": "222.73.202.226:2572",
        //     "startFrom": "2015-09-10T05:58:10.289+08:00",
        //     "status": "connected",
        //		 "bytesPerSecond": 16870.200000000001,
        //		 "framesPerSecond": {
        //		 		"audio": 42.200000000000003,
        //				"video": 14.733333333333333,
        //				"data": 0.066666666666666666
        //		 }
        // }
    }
});

Generate RTMP publish URL

var publishUrl = stream.rtmpPublishUrl();
console.log(publishUrl);
// rtmp://scv02k.publish.z1.pili.qiniup.com/coding/55d7f934e3ba5723280000cb?key=new_secret_words

Generate RTMP live play URLs

var urls = stream.rtmpLiveUrls();
console.log(urls);
// {
//     'ORIGIN': 'rtmp://scv02k.live1-rtmp.z1.pili.qiniucdn.com/coding/55d7f934e3ba5723280000cb'
// }

Generate HLS live play URLs

var urls = stream.hlsLiveUrls();
console.log(urls);
// {
//     'ORIGIN': 'http://scv02k.live1-http.z1.pili.qiniucdn.com/coding/55d7f934e3ba5723280000cb.m3u8'
// }

Generate Http-Flv live play URLs

var urls = stream.httpFlvLiveUrls();
console.log(urls);
// {
//     'ORIGIN': 'http://scv02k.live1-http.z1.pili.qiniucdn.com/coding/55d7f934e3ba5723280000cb.flv'
// }

Get Stream segments

var options = {
   startTime : null,	// optional, in second, unix timestamp
   endTime   : null,	// optional, in second, unix timestamp
   limit     : null	// optional
};

stream.segments(options, function(err, segments) {
   if (!err) {
	   console.log(segments);
	   // Log stream segments
	   // [
	   //     {
	   //         "start": 1440196065,
	   //         "end": 1440196124
	   //     },
	   //     {
	   //         "start": 1440198072,
	   //         "end": 1440198092
	   //     },
	   //     ...
	   // ]
   }
});

Generate HLS playback URLs

var start = 1440196065; // required, in second, unix timestamp
var end   = 1440196105; // required, in second, unix timestamp

var urls = stream.hlsPlaybackUrls(start, end);
console.log(urls);
// {
//     ORIGIN: 'http://scv02k.playback1.z1.pili.qiniucdn.com/coding/55d7fa0ee3ba5723280000cc.m3u8?start=1440196065&end=1440196105'
// }

Save Stream as a file

var name   = 'videoName.mp4';	// required
var start  = 1440196065;	// required, in second, unix timestamp
var end    = 1440196105;	// required, in second, unix timestamp
var format = 'mp4';		// optional

var options = {
	notifyUrl : null,	// optional
    pipeline : null     // optional
};

stream.saveAs(name, format, start, end, options, function(err, responseData) {
	console.log(responseData);
	// Log responseData
	// {
	//     "url": "http://scv02k.media1.z1.pili.qiniucdn.com/recordings/z1.coding.55d7faf0e3ba5723280000cd/videoName.m3u8",
	//     "targetUrl": "http://scv02k.vod1.z1.pili.qiniucdn.com/recordings/z1.coding.55d7faf0e3ba5723280000cd/videoName.mp4",
	//     "persistentId": "z1.55d7a6e77823de5a49a8899b"
	// }
});

While invoking saveAs() and snapshot(), you can get processing state via Qiniu FOP Service using persistentId.
API: curl -D GET http://api.qiniu.com/status/get/prefop?id={PersistentId}
Doc reference: http://developer.qiniu.com/docs/v6/api/overview/fop/persistent-fop.html#pfop-status

Snapshot Stream

var name   = 'imageName.jpg';	// required
var format = 'jpg';		// required

var options = {
	time		: 1440196100,	// optional, default as now, in second, unix timestamp
	notifyUrl	: null		// optional
};

stream.snapshot(name, format, options, function(err, responseData) {
	console.log(responseData);
	// Log responseData
	// {
	// 	"targetUrl": "http://scv02k.static1.z1.pili.qiniucdn.com/snapshots/z1.coding.55d7faf0e3ba5723280000cd/imageName.jpg",
	// 	"persistentId": "z1.55d7a6e77823de5a49a8899a"
	// }
});

Delete a Stream

hub.deleteStream(streamId, function(err, data) {
    console.log(data);
    // null
});

History

  • 1.5.5
    • fixed token url generate bug.
  • 1.5.4
    • Add pipeline in saveAs
  • 1.5.3
    • Use saveAs in hlsPlaybackUrls, need async function
  • 1.5.2
    • Update Stream's hosts
    • Add startFrom in Stream status
  • 1.5.0
    • Rename Client to Hub
    • Add Credentials
  • 1.4.0
    • Update stream struct
    • Add stream.snapshot()
    • Add stream.enable()
    • Add stream.disable()
    • Add stream.httpFlvLiveUrls()
    • Update stream.status()
    • Update stream.toJSONString()
    • Update stream.segments()
    • Update hub.listStreams()
  • 1.2.1
    • Add stream saveas function
  • 1.2.0
    • Update Stream object
    • Add new Stream functions
    • Update Client functions
  • 1.0.7
    • Fix import bug
  • 1.0.6
    • Fix GET request query method
    • Add more defensive code to improve robustness
  • 1.0.5
    • Fix dynamic RTMP publish URL nonce generate bug
  • 1.0.4
    • Add server error handle
    • Fix merge bugs
  • 1.0.2
    • Update client create function
    • Update optional params
    • Add disabled field in Stream
    • Add getStreamStatus function in Client
  • 1.0.1
    • Update Stream publish and play url generate functions
  • 1.0.0
    • Init sdk
    • Add Stream API
    • Add publish and play policy