forked from NoRulesJustFeels/Caster
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
a2b7c00
commit b11a780
Showing
35 changed files
with
4,047 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<classpath> | ||
<classpathentry kind="src" path="src"/> | ||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/> | ||
<classpathentry kind="lib" path="libs/commons-logging-1.1.1.jar"/> | ||
<classpathentry kind="lib" path="libs/httpclient-4.2.5.jar"/> | ||
<classpathentry kind="lib" path="libs/httpcore-4.2.4.jar"/> | ||
<classpathentry kind="lib" path="libs/java_websocket.jar"/> | ||
<classpathentry kind="lib" path="libs/jna-3.5.2.jar"/> | ||
<classpathentry kind="lib" path="libs/json-simple-1.1.1.jar"/> | ||
<classpathentry kind="lib" path="libs/platform-3.5.2.jar"/> | ||
<classpathentry kind="lib" path="libs/vlcj-2.4.1.jar"/> | ||
<classpathentry kind="lib" path="libs/commons-cli-1.2.jar"/> | ||
<classpathentry kind="output" path="bin"/> | ||
</classpath> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<projectDescription> | ||
<name>Caster</name> | ||
<comment></comment> | ||
<projects> | ||
</projects> | ||
<buildSpec> | ||
<buildCommand> | ||
<name>org.eclipse.jdt.core.javabuilder</name> | ||
<arguments> | ||
</arguments> | ||
</buildCommand> | ||
</buildSpec> | ||
<natures> | ||
<nature>org.eclipse.jdt.core.javanature</nature> | ||
</natures> | ||
</projectDescription> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
#Mon Sep 02 18:50:19 CDT 2013 | ||
eclipse.preferences.version=1 | ||
encoding//src/com/entertailion/java/caster/Main.java=UTF-8 | ||
encoding//src/com/entertailion/java/caster/Playback.java=UTF-8 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
#Wed Aug 28 15:42:28 CDT 2013 | ||
eclipse.preferences.version=1 | ||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled | ||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 | ||
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve | ||
org.eclipse.jdt.core.compiler.compliance=1.6 | ||
org.eclipse.jdt.core.compiler.debug.lineNumber=generate | ||
org.eclipse.jdt.core.compiler.debug.localVariable=generate | ||
org.eclipse.jdt.core.compiler.debug.sourceFile=generate | ||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error | ||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error | ||
org.eclipse.jdt.core.compiler.source=1.6 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,89 @@ | ||
Caster | ||
====== | ||
|
||
Caster | ||
<p><img src="http://chromecast.entertailion.com/chromecastanimation100.gif"/></p> | ||
|
||
<p>Caster is a command-line application to beam video files to <a href="https://www.google.com/intl/en/chrome/devices/chromecast/">ChromeCast</a> devices. It is useful for automation and scripting use cases.</p> | ||
|
||
<p>To run the application, you need a <a href="http://www.oracle.com/technetwork/java/javase/downloads/index.html">Java runtime environment (JRE)</a> for your operating system. </p> | ||
|
||
<p>There is a dependency on a web app that needs to be <a href="https://developers.google.com/cast/whitelisting#whitelist-receiver">registered with Google</a>.</p> | ||
|
||
<p>Caster provides several command line options which are self-documented with the '-h' option: | ||
<blockquote> | ||
java -jar caster.jar -h | ||
usage: java -jar caster.jar [-d <arg>] [-f <arg>] [-h] [-id <arg>] [-l] [-s] | ||
[-t] [-tp <arg>] [-v] [-V] | ||
-d,--device <arg> ChromeCast device IP address | ||
-f,--file <arg> Local media file; -d also required | ||
-h,--help Print this help message | ||
-id,--app-id <arg> App ID for whitelisted device | ||
-l,--list List ChromeCast devices | ||
-s,--stream HTTP URL for streaming content; -d also | ||
required | ||
-t,--transcode Transcode media; -f also required | ||
-tp,--transcode-parameters <arg> Transcode parameters; -t also required | ||
-v,--verbose Verbose logging | ||
-V,--version Print version information | ||
</blockquote></p> | ||
|
||
<p>Here are some examples of using Caster: | ||
<ul> | ||
<li>Get the list of ChromeCast devices (there is a 10 second delay for finding the devices on the local network): | ||
<blockquote> | ||
java -jar caster.jar -l | ||
</blockquote> | ||
</li> | ||
<ul> | ||
<li>Play a stream from the internet on the ChromeCast device with IP address 192.168.0.22: | ||
<blockquote> | ||
java -jar caster.jar -d 192.168.0.22 -s "http://commondatastorage.googleapis.com/gtv-videos-bucket/big_buck_bunny_1080p.mp4" | ||
</blockquote> | ||
</li> | ||
<li>Play a local file: | ||
<blockquote> | ||
java -jar caster.jar -d 192.168.0.22 -f "/Users/leon_nicholls/Downloads/video.mp4" | ||
</blockquote> | ||
</li> | ||
<li>Transcode a local file: | ||
<blockquote> | ||
java -jar caster.jar -d 192.168.0.22 -t -f "/Users/leon_nicholls/Downloads/video.wmv" | ||
</blockquote> | ||
</li> | ||
<li>Transcode a local file with custom VLC transcoding parameters: | ||
<blockquote> | ||
java -jar caster.jar -d 192.168.0.22 -t -tp "vcodec=VP80,vb=2000,vfilter=canvas{width=640,height=360}, acodec=vorb,ab=128,channels=2,samplerate=44100,threads=2" -f "/Users/leon_nicholls/Downloads/video.wmv" | ||
</blockquote> | ||
</li> | ||
</ul> | ||
|
||
<p>ChromeCast devices only support a limited number of <a href="https://developers.google.com/cast/supported_media_types">media formats</a>. | ||
Caster has experimental support for converting other media formats into <a href="http://en.wikipedia.org/wiki/WebM">WebM</a> using the <a href="https://github.com/caprica/vlcj">vlcj library</a> for <a href="http://www.videolan.org/index.html">VLC</a>. | ||
You need to <a href="http://www.videolan.org/vlc/#download">download</a> and install VLC for your computer (the latest 64-bit version is preferred). For Windows, you need to install the <a href="http://download.videolan.org/pub/videolan/vlc/last/win64/">64-bit experimental version</a>. | ||
<b>If you have the 64-bit version of Java, you have to install the 64-bit version of VLC</b>. By default Caster uses the following <a href="http://www.videolan.org/doc/streaming-howto/en/ch03.html#id346868">VLC transcoding parameters</a>: | ||
<blockquote> | ||
:sout=#transcode{vcodec=VP80,vb=1000,vfilter=canvas{width=640,height=360}, acodec=vorb,ab=128,channels=2,samplerate=44100,threads=2} :http{mux=webm,dst=:8087/cast.webm} :sout-keep | ||
</blockquote> | ||
<b>Note that converting video is very CPU intensive. It might take several seconds for the video to start playing on your ChromeCast device</b>. | ||
</p> | ||
|
||
<p>The computer running the Caster application needs to be on the same network as the ChromeCast device. | ||
To play the video, a web server is created on port 8080 on your computer and you might have to configure your firewall to allow incoming connections to access the video.</p> | ||
|
||
<p>Caster doesn't provide command-line playback controls. You can use an Android app like <a href="https://play.google.com/store/apps/details?id=com.benlc.camcast">RemoteCast</a> to remotely control the media playback.</p> | ||
|
||
<p>Note for developers: You need to put your own app ID in the Main.java and receiver index.html files. Upload the receiver index.html file to your whitelisted app URL. Generate the caster.jar file from the source code. | ||
This <a href="https://dl.dropboxusercontent.com/u/17958951/caster.jar">caster.jar</a> build can be used with your own "-id" app id as a command-line parameter.</p> | ||
|
||
<p>Other apps developed by Entertailion: | ||
<ul> | ||
<li><a href="https://github.com/entertailion/Fling">Fling</a>: GUI to beam video files from computers to ChromeCast devices.</li> | ||
<li><a href="https://github.com/entertailion/DIAL">DIAL</a>: ChromeCast device discovery and YouTube playback.</li> | ||
<li><a href="https://play.google.com/store/apps/details?id=com.entertailion.android.tvremote">Able Remote for Google TV</a>: The ultimate Google TV remote</li> | ||
<li><a href="https://play.google.com/store/apps/details?id=com.entertailion.android.launcher">Open Launcher for Google TV</a>: The ultimate Google TV launcher</li> | ||
<li><a href="https://play.google.com/store/apps/details?id=com.entertailion.android.overlay">Overlay for Google TV</a>: Live TV effects for Google TV</li> | ||
<li><a href="https://play.google.com/store/apps/details?id=com.entertailion.android.overlaynews">Overlay News for Google TV</a>: News headlines over live TV</li> | ||
<li><a href="https://play.google.com/store/apps/details?id=com.entertailion.android.videowall">Video Wall</a>: Wall-to-Wall Youtube videos</li> | ||
<li><a href="https://play.google.com/store/apps/details?id=com.entertailion.android.tasker">GTV Tasker Plugin</a>: Control your Google TV with Tasker actions</li> | ||
</ul> | ||
</p> |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
<!-- | ||
Copyright (C) 2013 Google Inc. All Rights Reserved. | ||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
--> | ||
|
||
<!DOCTYPE html> | ||
<html> | ||
<script src="https://www.gstatic.com/cast/js/receiver/1.0/cast_receiver.js"></script> | ||
<script type="text/javascript"> | ||
|
||
cast.receiver.logger.setLevelValue(0); | ||
|
||
// Initialize and start the media playing receiver | ||
// TODO Add your own app id here | ||
var receiver = new cast.receiver.Receiver( | ||
'YOUR_APP_ID_HERE', | ||
[cast.receiver.RemoteMedia.NAMESPACE], | ||
"", | ||
5); | ||
var remoteMedia = new cast.receiver.RemoteMedia(); | ||
remoteMedia.addChannelFactory( | ||
receiver.createChannelFactory(cast.receiver.RemoteMedia.NAMESPACE)); | ||
|
||
receiver.start(); | ||
|
||
window.addEventListener('load', function() { | ||
var elem = document.getElementById('vid'); | ||
remoteMedia.setMediaElement(elem); | ||
|
||
var checkStatus = function() { | ||
var status = document.getElementById('status'); | ||
var st = remoteMedia.getStatus()['state']; | ||
|
||
if( st == 0 || remoteMedia.getStatus()['current_time'] == 0 ) { | ||
status.style.display = 'block'; | ||
} | ||
else { | ||
if( st == 1 && remoteMedia.getStatus()['current_time'] > 0 ) { | ||
status.innerHTML = 'Paused...'; | ||
status.style.display = 'block'; | ||
} | ||
else { | ||
status.innerHTML = remoteMedia.getStatus()['current_time']; | ||
status.style.display = 'none'; | ||
elem.style.display = 'block'; | ||
} | ||
} | ||
} | ||
setInterval(checkStatus, 1000); | ||
|
||
}); | ||
</script> | ||
<title>Caster</title> | ||
<body> | ||
<video id="vid" | ||
style="position:absolute;top:0;left:0;height:100%;width:100%"> | ||
<div id="status" style="display:none; font-size:300%; position:absolute;top:40%;left:40%;"> | ||
<img src="/images/chrome_loading.gif" width="60%"> | ||
</div> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
package com.entertailion.java.caster; | ||
|
||
/* | ||
* Copyright (C) 2013 ENTERTAILION LLC | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
import org.xml.sax.Attributes; | ||
import org.xml.sax.SAXException; | ||
import org.xml.sax.helpers.DefaultHandler; | ||
|
||
/** | ||
* XML parser for DIAL app responses | ||
* | ||
* @author leon_nicholls | ||
* | ||
*/ | ||
public class AppHandler extends DefaultHandler { | ||
|
||
private static final String LOG_TAG = "AppHandler"; | ||
|
||
private String connectionServiceUrl; | ||
private String state; | ||
private String protocol; | ||
|
||
// Current characters being accumulated | ||
private StringBuffer chars = new StringBuffer(); | ||
|
||
public AppHandler() { | ||
} | ||
|
||
@Override | ||
public void endDocument() throws SAXException { | ||
// Nothing | ||
} | ||
|
||
@Override | ||
public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException { | ||
chars.delete(0, chars.length()); | ||
|
||
} | ||
|
||
@Override | ||
public void endElement(String namespaceURI, String localName, String qName) throws SAXException { | ||
if ("connectionSvcURL".equals(qName)) { | ||
connectionServiceUrl = chars.toString(); | ||
} else if ("state".equals(qName)) { | ||
state = chars.toString(); | ||
} else if ("protocol".equals(qName)) { | ||
protocol = chars.toString(); | ||
} | ||
} | ||
|
||
@Override | ||
public void characters(char ch[], int start, int length) { | ||
chars.append(new String(ch, start, length)); | ||
} | ||
|
||
public String getConnectionServiceUrl() { | ||
return connectionServiceUrl; | ||
} | ||
|
||
public void setConnectionServiceUrl(String connectionServiceUrl) { | ||
this.connectionServiceUrl = connectionServiceUrl; | ||
} | ||
|
||
public String getState() { | ||
return state; | ||
} | ||
|
||
public void setState(String state) { | ||
this.state = state; | ||
} | ||
|
||
public String getProtocol() { | ||
return protocol; | ||
} | ||
|
||
public void setProtocol(String protocol) { | ||
this.protocol = protocol; | ||
} | ||
|
||
} |
59 changes: 59 additions & 0 deletions
59
src/com/entertailion/java/caster/BroadcastAdvertisement.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
/* | ||
* Copyright (C) 2013 ENTERTAILION, LLC. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except | ||
* in compliance with the License. You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software distributed under the License | ||
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express | ||
* or implied. See the License for the specific language governing permissions and limitations under | ||
* the License. | ||
*/ | ||
|
||
package com.entertailion.java.caster; | ||
|
||
import java.net.InetAddress; | ||
|
||
/* | ||
HTTP/1.1 200 OK | ||
USN: uuid:d17c2986-4624-3f2c-93a5-fe3ef0a0ec9c::urn:dial-multiscreen-org:service:dial:1 | ||
LOCATION: http://192.168.0.51:47944/dd.xml | ||
BOOTID.UPNP.ORG: 1287126024 | ||
ST: urn:dial-multiscreen-org:service:dial:1 | ||
CACHE-CONTROL: max-age=1800 | ||
EXT | ||
*/ | ||
|
||
/** | ||
* DIAL Broadcast Advertisement | ||
* | ||
* @author leon_nicholls | ||
* | ||
*/ | ||
|
||
public final class BroadcastAdvertisement { | ||
|
||
private final String location; | ||
private final InetAddress ipAddress; | ||
private final int port; | ||
|
||
BroadcastAdvertisement(String location, InetAddress ipAddress, int port) { | ||
this.location = location; | ||
this.ipAddress = ipAddress; | ||
this.port = port; | ||
} | ||
|
||
public String getLocation() { | ||
return location; | ||
} | ||
|
||
public InetAddress getIpAddress() { | ||
return ipAddress; | ||
} | ||
|
||
public int getPort() { | ||
return port; | ||
} | ||
} |
Oops, something went wrong.