Comparar commits
16 Commits
| Autor | SHA1 | Data | |
|---|---|---|---|
| c3961cd529 | |||
| 97731ccc21 | |||
| 1d92429959 | |||
| a63bc605e0 | |||
| 654dc7305d | |||
| ca3c981bde | |||
| 6e9d091c1e | |||
| 99afa2722b | |||
| ff435704fd | |||
| d48349658c | |||
| a7a330e90a | |||
| 559a644939 | |||
| 34616ba861 | |||
| 62b4622c2a | |||
| 87c6ab6bbd | |||
| 1454b41f94 |
+46
-33
@@ -1,16 +1,15 @@
|
||||
# castnow
|
||||
|
||||
castnow is commandline utility which can be used to playback media files on
|
||||
your chromecast device. It supports playback of local video files, youtube
|
||||
clips, videos on the web and torrents. You can also re-attach a running
|
||||
playback session.
|
||||
castnow is a command-line utility that can be used to play back media files on
|
||||
your Chromecast device. It supports playback of local video files, videos on the web and torrents.
|
||||
You can also re-attach a running playback session \(this sentence should belong somewhere else).
|
||||
|
||||
### interested in beeing a castnow maintainer?
|
||||
### interested in being a castnow maintainer?
|
||||
|
||||
I currently don't have that much time to maintain this project and also lost some interest (to be honest).
|
||||
Main reason is that we have a new TV since a few months which supports casting to it directly using
|
||||
DLNA (you may wanna checkout [dlnacast](https://github.com/xat/dlnacast)).
|
||||
Feel free to contact me ( [simon@sope.io](simon@sope.io) ) if you want to be added as maintainer to castnow.
|
||||
I currently don't have that much time to maintain this project and have also lost some interest (to be honest).
|
||||
Main reason is that we have had a new TV for a few months that supports casting directly to it using
|
||||
DLNA \(you may wanna checkout [dlnacast](https://github.com/xat/dlnacast)).
|
||||
Feel free to contact me \( [simon@sope.io](simon@sope.io) ) if you want to be added as a maintainer to castnow.
|
||||
|
||||
### usage
|
||||
|
||||
@@ -25,54 +24,58 @@ castnow ./mydirectory/
|
||||
// playback 3 videos after each other
|
||||
castnow video1.mp4 video2.mp4 video3.mp4
|
||||
|
||||
// start playback of some mp4 file over the web
|
||||
// start playback of an mp4 file over the web
|
||||
castnow http://commondatastorage.googleapis.com/gtv-videos-bucket/ED_1280.mp4
|
||||
|
||||
// start playback of some youtube clip
|
||||
castnow https://www.youtube.com/watch?v=pcVRrlmpcWk
|
||||
|
||||
// start playback of some video over torrent
|
||||
// start playback of a video over torrent
|
||||
castnow <url-to-torrent-file OR magnet>
|
||||
|
||||
// start playback of some video over torrent, with local subtitles
|
||||
// start playback of a video over torrent with local subtitles
|
||||
castnow <url-to-torrent-file OR magnet> --subtitles </local/path/to/subtitles.srt>
|
||||
|
||||
// transcode some other videoformat to mp4 while playback (requires ffmpeg)
|
||||
// transcode some other video format to mp4 while playback (requires ffmpeg)
|
||||
castnow ./myvideo.avi --tomp4
|
||||
|
||||
// re-attach to an currently running playback session
|
||||
// re-attach to a currently running playback session
|
||||
castnow
|
||||
|
||||
```
|
||||
|
||||
### options
|
||||
|
||||
* `--tomp4` Transcode a video file to mp4 while playback. This option requires
|
||||
* `--tomp4` Transcode a video file to mp4 during playback. This option requires
|
||||
ffmpeg to be installed on your computer. The play / pause controls are currently
|
||||
not supported in transcode mode.
|
||||
|
||||
* `--device "my chromecast"` If you have more than one chromecast in your network
|
||||
* `--device "my chromecast"` If you have more than one Chromecast on your network,
|
||||
use the `--device` option to specify the device on which you want to start casting.
|
||||
Otherwise castnow will just use the first device it finds in the network.
|
||||
Otherwise, castnow will just use the first device it finds in the network.
|
||||
|
||||
* `--address <IP>` The IP address of your chromecast. This will skip the MDNS scan.
|
||||
* `--address 192.168.1.4` The IP address or hostname of your chromecast. This will skip
|
||||
the MDNS scan.
|
||||
|
||||
* `--subtitles <path/URL>` This can be a path or URL to a vtt or srt file which
|
||||
* `--subtitles <path/URL>` This can be a path or URL to a vtt or srt file that
|
||||
contains subtitles.
|
||||
|
||||
* `--myip <IP>` Your main IP address (useful if you have multiple network adapters)
|
||||
* `--subtitle-scale 1.5` Scaling factor for the size of the subtitle font. Default is 1.0.
|
||||
|
||||
* `--subtitle-color #FFFFFFFF` Foreground RGBA color of the subtitle font.
|
||||
|
||||
* `--myip 192.168.1.8` Your main IP address \(useful if you have multiple network adapters)
|
||||
|
||||
* `--quiet` Hide the player timeline.
|
||||
|
||||
* `--peerflix-* <val>` Pass options to peerflix.
|
||||
* `--peerflix-<option> <argument>` Pass options to peerflix.
|
||||
|
||||
* `--ffmpeg-* <val>` Pass options to ffmpeg.
|
||||
* `--ffmpeg-<option> <argument>` Pass options to ffmpeg.
|
||||
|
||||
* `--type <val>` Explicity set the mime-type of the first item in the playlist (e.g. 'video/mp4').
|
||||
* `--type <type>` Explicity set the mime-type of the first item in the playlist (e.g. 'video/mp4').
|
||||
|
||||
* `--seek <val>` Seek to the specified time on start using the format hh:mm:ss or mm:ss.
|
||||
* `--seek <hh:mm:ss>` Seek to the specified time on start using the format hh:mm:ss or mm:ss.
|
||||
|
||||
* `--bypass-srt-encoding` Disable automatic UTF8 encoding of SRT subtitles.
|
||||
* `--bypass-srt-encoding` Disable automatic UTF-8 encoding of SRT subtitles.
|
||||
|
||||
* `--loop` Play the list of files over and over in a loop, forever.
|
||||
|
||||
* `--help` Display help message.
|
||||
|
||||
@@ -81,7 +84,7 @@ contains subtitles.
|
||||
```
|
||||
|
||||
space // toggle between play and pause
|
||||
m // toggle between mute and unmute
|
||||
m // toggle mute
|
||||
up // volume up
|
||||
down // volume down
|
||||
left // seek backward (keep pressed / multiple press for faster seek)
|
||||
@@ -92,21 +95,31 @@ q // quit
|
||||
|
||||
```
|
||||
|
||||
### YouTube support
|
||||
|
||||
We had to drop direct YouTube support for now since google changed the chromecast YouTube API.
|
||||
However, there is a nice workaround in combination with the tool [youtube-dl](https://github.com/rg3/youtube-dl):
|
||||
|
||||
`youtube-dl -o - https://youtu.be/BaW_jenozKc | castnow --quiet -`
|
||||
|
||||
Thanks to [trulex](https://github.com/trulex) for pointing that out.
|
||||
|
||||
### reporting bugs/issues
|
||||
|
||||
Please always append the debug output to your issues. You can enable the debug messages by setting the
|
||||
DEBUG ENV variable before running the castnow-command like this: `DEBUG=castnow* castnow ./myvideo.mp4`.
|
||||
Some problems are also already addressed in our wiki https://github.com/xat/castnow/wiki.
|
||||
Please include the debug output in your issues. You can enable the debug messages by setting the
|
||||
DEBUG environment variable before running the castnow command like this: `DEBUG=castnow* castnow ./myvideo.mp4`.
|
||||
Some problems have already been addressed in our wiki https://github.com/xat/castnow/wiki.
|
||||
|
||||
### installation
|
||||
|
||||
`npm install castnow -g`
|
||||
|
||||
### contributers
|
||||
### contributors
|
||||
|
||||
* [tooryx](https://github.com/tooryx)
|
||||
* [przemyslawpluta](https://github.com/przemyslawpluta)
|
||||
|
||||
## License
|
||||
Copyright (c) 2015 Simon Kusterer
|
||||
|
||||
Licensed under the MIT license.
|
||||
|
||||
+21
-16
@@ -16,9 +16,9 @@ var noop = function() {};
|
||||
var directories = require('./plugins/directories');
|
||||
var localfile = require('./plugins/localfile');
|
||||
var torrent = require('./plugins/torrent');
|
||||
var youtube = require('./plugins/youtube');
|
||||
var transcode = require('./plugins/transcode');
|
||||
var subtitles = require('./plugins/subtitles');
|
||||
var stdin = require('./plugins/stdin');
|
||||
|
||||
if (opts.help) {
|
||||
return console.log([
|
||||
@@ -26,25 +26,28 @@ if (opts.help) {
|
||||
'Usage: castnow [<media>, <media>, ...] [OPTIONS]',
|
||||
'',
|
||||
'Option Meaning',
|
||||
'--tomp4 Convert file to mp4 while playback',
|
||||
'--device <name> The name of the chromecast device that should be used',
|
||||
'--address <ip> The IP address of your chromecast device',
|
||||
'--tomp4 Convert file to mp4 during playback',
|
||||
'--device <name> The name of the Chromecast device that should be used',
|
||||
'--address <ip> The IP address or hostname of your Chromecast device',
|
||||
'--subtitles <path/url> Path or URL to an SRT or VTT file',
|
||||
'--myip <ip> Your main IP address',
|
||||
'--quiet No output',
|
||||
'--subtitle-scale <scale> Subtitle font scale',
|
||||
'--subtitle-color <color> Subtitle font RGBA color',
|
||||
'--myip <ip> Your local IP address',
|
||||
'--quiet No output',
|
||||
'--peerflix-* <value> Pass options to peerflix',
|
||||
'--ffmpeg-* <value> Pass options to ffmpeg',
|
||||
'--type <val> Explicity set the mime-type (e.g. "video/mp4")',
|
||||
'--bypass-srt-encoding Disable automatic UTF8 encoding of SRT subtitles',
|
||||
'--seek <value> Seek to the specified time on start using the format hh:mm:ss or mm:ss',
|
||||
'--type <type> Explicitly set the mime-type (e.g. "video/mp4")',
|
||||
'--bypass-srt-encoding Disable automatic UTF-8 encoding of SRT subtitles',
|
||||
'--seek <hh:mm:ss> Seek to the specified time on start using the format hh:mm:ss or mm:ss',
|
||||
'--loop Loop over playlist, or file, forever',
|
||||
|
||||
'--help This help screen',
|
||||
'',
|
||||
'Player controls',
|
||||
'',
|
||||
'Key Meaning',
|
||||
'Key Action',
|
||||
'space Toggle between play and pause',
|
||||
'm Toggle between mute and unmute',
|
||||
'm Toggle mute',
|
||||
'up Volume Up',
|
||||
'down Volume Down',
|
||||
'left Seek backward',
|
||||
@@ -161,7 +164,8 @@ var ctrl = function(err, p, ctx) {
|
||||
ui.showLabels('state');
|
||||
debug('loading next in playlist: %o', playlist[0]);
|
||||
p.load(playlist[0], noop);
|
||||
playlist.shift();
|
||||
var file = playlist.shift();
|
||||
if (ctx.options.loop) playlist.push(file)
|
||||
});
|
||||
};
|
||||
|
||||
@@ -186,8 +190,8 @@ var ctrl = function(err, p, ctx) {
|
||||
|
||||
// toggle between mute / unmute
|
||||
m: function() {
|
||||
if(!volume) {
|
||||
return;
|
||||
if(!volume) {
|
||||
return;
|
||||
} else if (volume.muted) {
|
||||
p.unmute(function(err, status) {
|
||||
if (err) return;
|
||||
@@ -278,17 +282,18 @@ player.use(function(ctx, next) {
|
||||
next();
|
||||
});
|
||||
|
||||
player.use(stdin);
|
||||
player.use(directories);
|
||||
player.use(torrent);
|
||||
player.use(localfile);
|
||||
player.use(youtube);
|
||||
player.use(transcode);
|
||||
player.use(subtitles);
|
||||
|
||||
player.use(function(ctx, next) {
|
||||
if (ctx.mode !== 'launch') return next();
|
||||
ctx.options = xtend(ctx.options, ctx.options.playlist[0]);
|
||||
ctx.options.playlist.shift();
|
||||
var file = ctx.options.playlist.shift();
|
||||
if (ctx.options.loop) ctx.options.playlist.push(file);
|
||||
next();
|
||||
});
|
||||
|
||||
|
||||
+3
-4
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "castnow",
|
||||
"version": "0.4.14",
|
||||
"version": "0.4.17",
|
||||
"description": "commandline chromecast player",
|
||||
"main": "index.js",
|
||||
"bin": {
|
||||
@@ -34,19 +34,18 @@
|
||||
"debounced-seeker": "^1.0.0",
|
||||
"debug": "^2.1.0",
|
||||
"fs-extended": "^0.2.0",
|
||||
"get-youtube-id": "^0.1.3",
|
||||
"got": "^1.2.2",
|
||||
"internal-ip": "^1.0.0",
|
||||
"keypress": "^0.2.1",
|
||||
"mime": "^1.2.11",
|
||||
"minimist": "^1.1.0",
|
||||
"peerflix": "^0.29.1",
|
||||
"peerflix": "^0.34.0",
|
||||
"playerui": "^1.2.0",
|
||||
"query-string": "^1.0.0",
|
||||
"range-parser": "^1.0.2",
|
||||
"read-torrent": "^1.0.0",
|
||||
"router": "^0.6.2",
|
||||
"srt2vtt": "^1.2.0",
|
||||
"srt2vtt": "^1.3.1",
|
||||
"stream-transcoder": "0.0.5",
|
||||
"xml2js": "^0.4.4",
|
||||
"xtend": "^4.0.0"
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
var http = require('http');
|
||||
var internalIp = require('internal-ip');
|
||||
var debug = require('debug')('castnow:stdin');
|
||||
|
||||
var port = 4104;
|
||||
|
||||
var isStdin = function(item) {
|
||||
return '-'===item.path;
|
||||
};
|
||||
|
||||
|
||||
var stdin = function(ctx, next) {
|
||||
debug(ctx.options.playlist);
|
||||
if (ctx.mode !== 'launch') return next();
|
||||
if (ctx.options.playlist.length != 1 || !isStdin(ctx.options.playlist[0])) return next();
|
||||
|
||||
var ip = ctx.options.myip || internalIp();
|
||||
ctx.options.playlist[0] = {
|
||||
path: 'http://' + ip + ':' + port,
|
||||
type: 'video/mp4'
|
||||
};
|
||||
|
||||
http.createServer(function(req, res){
|
||||
process.stdin.pipe(res);
|
||||
}).listen(port);
|
||||
|
||||
debug('started webserver for stdin on address %s using port %s', ip, port);
|
||||
next();
|
||||
|
||||
};
|
||||
|
||||
module.exports = stdin;
|
||||
@@ -31,10 +31,10 @@ var attachSubtitles = function(ctx) {
|
||||
}
|
||||
ctx.options.playlist[0].media.textTrackStyle = {
|
||||
backgroundColor: '#00000000',
|
||||
foregroundColor: '#FFFF00FF',
|
||||
foregroundColor: ctx.options['subtitle-color'] || '#FFFF00FF',
|
||||
edgeType: 'OUTLINE',
|
||||
edgeColor: '#000000FF',
|
||||
fontScale: 1,
|
||||
fontScale: ctx.options['subtitle-scale'],
|
||||
fontStyle: 'NORMAL',
|
||||
fontFamily: 'Droid Sans',
|
||||
fontGenericFamily: 'SANS_SERIF',
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
var Api = require('chromecast-player').api;
|
||||
var castv2Cli = require('castv2-client');
|
||||
var RequestResponseController = castv2Cli.RequestResponseController;
|
||||
var inherits = require('util').inherits;
|
||||
var getYouTubeId = require('get-youtube-id');
|
||||
var debug = require('debug')('castnow:youtube');
|
||||
|
||||
var Yt = function() {
|
||||
Api.apply(this, arguments);
|
||||
this.ytreq = this.createController(RequestResponseController,
|
||||
'urn:x-cast:com.google.youtube.mdx');
|
||||
};
|
||||
|
||||
Yt.APP_ID = '233637DE';
|
||||
|
||||
inherits(Yt, Api);
|
||||
|
||||
Yt.prototype.load = function(options, cb) {
|
||||
var youtubeId = getYouTubeId(options.path);
|
||||
debug('loading video with id %s', youtubeId);
|
||||
var opts = {
|
||||
type: 'flingVideo',
|
||||
data: {
|
||||
currentTime: 0,
|
||||
videoId: youtubeId
|
||||
}
|
||||
};
|
||||
this.ytreq.request(opts);
|
||||
if (cb) cb();
|
||||
};
|
||||
|
||||
var youtube = function(ctx, next) {
|
||||
if (ctx.mode !== 'launch') return next();
|
||||
if (!getYouTubeId(ctx.options.playlist[0].path)) return next();
|
||||
debug('using youtube api');
|
||||
ctx.api = Yt;
|
||||
next();
|
||||
};
|
||||
|
||||
module.exports = youtube;
|
||||
Referência em uma Nova Issue
Bloquear um usuário