Git Product home page Git Product logo

casty's Introduction

Project no longer maintained

This project is no longer maintained. If you have any questions contact [email protected]

Casty

Casty is a small Android library that provides a simple media player for Chromecast. It's fully consistent with Google Cast v3.

Installation

Insert the following dependency to build.gradle file of your project:

dependencies {
    compile 'pl.droidsonroids:casty:1.0.8'
}

Usage

Casty requires Google Play Services and I assume that the target device has it installed (if not this example won't work). In a bigger project I suggest you check it using GoogleApiAvailability.

First, you need to initialize a Casty instance in every Activity you want to use it in:

public class MainActivity extends AppCompatActivity {
    private Casty casty;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        casty = Casty.create(this);
    }
}

If you want to add a Mini Controller widget, you can do it like this:

casty = Casty.create(this)
    .withMiniController();

Alternatively you can place it in your layout XML, just like in the official Google Cast example (remember to change fill_parent to match_parent 😆).

To support device discovery, add a menu item in overriden onCreateOptionsMenu method:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    super.onCreateOptionsMenu(menu);
    casty.addMediaRouteMenuItem(menu);
    getMenuInflater().inflate(R.menu.your_menu, menu);
    return true;
}

Automatically, Introduction Overlay (with text "Use this button to connect with Chromecast") will be shown at the first device discovery. If you want to change it or add another language override string with id casty_introduction_text in a XML resource.

You can also add a discovery button anywhere else by placing it in your layout XML:

<android.support.v7.app.MediaRouteButton
    android:id="@+id/media_route_button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />

And then set in up in your Activity:

MediaRouteButton mediaRouteButton = (MediaRouteButton) findViewById(R.id.media_route_button);
casty.setUpMediaRouteButton(mediaRouteButton);

You can add the above functionality (except MediaRouteButton) simply by extending CastyActivity. It will add a casty field and set up the rest:

public class MainActivity extends CastyActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        if (casty.isConnected()) {
            casty.getPlayer().loadMediaAndPlay(...)
        }
    }
}

All media player actions are included in a CastyPlayer object, which you can access by calling casty.getPlayer(). When you are connected to the device, you can play media the following way:

MediaData mediaData = new MediaData.Builder("http://distribution.bbb3d.renderfarming.net/video/mp4/bbb_sunflower_1080p_30fps_normal.mp4")
    .setStreamType(MediaData.STREAM_TYPE_BUFFERED) //required
    .setContentType("videos/mp4") //required
    .setMediaType(MediaData.MEDIA_TYPE_MOVIE)
    .setTitle("Sample title")
    .setSubtitle("Sample subtitle")
    .addPhotoUrl("https://peach.blender.org/wp-content/uploads/bbb-splash.png?x11217")
    .build();
casty.getPlayer().loadMediaAndPlay(mediaData);

Alternativly you can use loadMediaAndPlay(MediaInfo, autoPlay, position) similar to Google Cast example.

To react on Chromecast connect and disconnect events, you can simply register a listener:

casty.setOnConnectChangeListener(new Casty.OnConnectChangeListener() {
    @Override
    public void onConnected() {
        Log.d("Casty", "Connected with Chromecast");
    }
    
    @Override
    public void onDisconnected() {
        Log.d("Casty" "Disconnected from Chromecast");
    }
});

Custom usage

In case the library doesn't fit you, I left the possibility to change everything like in Google Cast v3. You can set receiver ID or even the whole CastOptions in your Application class:

Casty.configure(receiverId); //or
Casty.configure(customCastOptions);

Get CastContext by calling:

CastContext.getSharedInstance(context);

Get CastSession (so RemoteMediaClient) by register OnCastSessionUpdatedListener:

casty.setOnCastSessionUpdatedListener(new Casty.OnCastSessionUpdatedListener() {
    @Override
    public void onCastSessionUpdated(CastSession castSession) {
        if (castSession != null) {
            RemoteMediaClient remoteMediaClient = castSession.getRemoteMediaClient();
            //...
        }
    }
});

License

MIT

casty's People

Contributors

burnoo avatar koral-- avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

casty's Issues

RemoteServiceException$ForegroundServiceDidNotStartInTimeException

Hi, getting below error

android.app.StackTrace: Last startServiceCommon() call for this service was made here
at android.app.ContextImpl.startServiceCommon(ContextImpl.java:1876)
at android.app.ContextImpl.startForegroundService(ContextImpl.java:1831)
at android.content.ContextWrapper.startForegroundService(ContextWrapper.java:779)
at com.google.android.gms.internal.cast.zzah.zzg
at com.google.android.gms.internal.cast.zzah.onQueueStatusUpdated
at com.google.android.gms.cast.framework.media.zzr.onQueueStatusUpdated
at com.google.android.gms.internal.cast.zzdn.onQueueStatusUpdated
at com.google.android.gms.internal.cast.zzdn.zzp
at com.google.android.gms.cast.framework.media.RemoteMediaClient.onMessageReceived
at com.google.android.gms.internal.cast.zzcz.run
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at com.google.android.gms.internal.cast.zzep.dispatchMessage
at android.os.Looper.loopOnce(Looper.java:201)
at android.os.Looper.loop(Looper.java:288)
at android.app.ActivityThread.main(ActivityThread.java:7870)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)

android.app.RemoteServiceException$ForegroundServiceDidNotStartInTimeException: Context.startForegroundService() did not then call Service.startForeground(): ServiceRecord{92d22a8 u0 com.xyz/com.google.android.gms.cast.framework.media.MediaNotificationService}
at android.app.ActivityThread.generateForegroundServiceDidNotStartInTimeException(ActivityThread.java:1965)
at android.app.ActivityThread.throwRemoteServiceException(ActivityThread.java:1936)
at android.app.ActivityThread.access$2700(ActivityThread.java:256)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2190)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loopOnce(Looper.java:201)
at android.os.Looper.loop(Looper.java:288)
at android.app.ActivityThread.main(ActivityThread.java:7870)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)

OS: Android 12
Device: Pixel 6 Pro 

Incompatibility with Androidx?

Hi, im trying to use the library but i cant even implement it on my build.gradle.

as soon as i insert the line compile 'pl.droidsonroids:casty:1.0.8'

i get this compile error.

Error: Type com.google.android.gms.common.internal.zzf is referenced as an interface from com.google.android.gms.common.internal.zzac.

is it possible to be an incompatibility with androidx?

Play .m3u8 / HLS protocol on chromecast

Hi!

I'm following the tutorial for your library. I could connect to the chromecast successfully, if I play an mp4 video it works fine, but when i switch to an .m3u8 content it doesn't play it and no error is shown.

I wanted to ask you if HLS is supported in this project.

This is my code for playing a video. This is a sample video and not the real one since it's copyrighted. CORS is enabled with all the required headers, i'm pretty sure about it.

    String testUrl = "http://cdn-fms.rbs.com.br/vod/hls_sample1_manifest.m3u8";
    MediaData mediaData = new MediaData.Builder(testUrl)
            .setStreamType(MediaData.STREAM_TYPE_BUFFERED) //required
            .setContentType("application/x-mpegURL")
            .setMediaType(MediaData.MEDIA_TYPE_GENERIC)
            .setTitle(video.getName())
            .setSubtitle(video.getDescription())
            .addPhotoUrl(video.getThumbnail())
            .build();
    casty.getPlayer().loadMediaAndPlay(mediaData);

Thank you very much!

Playlist support in Casty

Is there any way to loadandplay the playlist in cast or Any API in casty to pass List of MediaData or Media Info

Cast to chromecast without preview on smartphone

Is this possible, to cast media without player preview on device (table/smartphone)? So I send video (or audio, or image) without player.
I develop B2B application, where need to user chromecast and it is required by technical task, that on smartphone sceen mustn't be preview of video, but another view.
So, is this possible to play media without showing preview to user?

proguard

my app crashes using this library with proguard

07-24 03:05:46.995 25441-25441/? E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.creativetrends.simple.app.pro, PID: 25441
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.creativetrends.simple.app.pro/com.creativetrends.simple.app.pro.main.VideoActivity}: java.lang.IllegalStateException: Failed to initialize CastContext.
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2690)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2755)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1495)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6196)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:888)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:778)
Caused by: java.lang.IllegalStateException: Failed to initialize CastContext.
at com.google.android.gms.cast.framework.CastContext.zzbu(Unknown Source)
at com.google.android.gms.cast.framework.CastContext.getSharedInstance(Unknown Source)
at pl.droidsonroids.casty.a.(Unknown Source)
at pl.droidsonroids.casty.a.a(Unknown Source)
at com.creativetrends.simple.app.pro.main.VideoActivity.onCreate(Unknown Source)
at android.app.Activity.performCreate(Activity.java:6698)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1140)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2643)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2755) 
at android.app.ActivityThread.-wrap12(ActivityThread.java) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1495) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:154) 
at android.app.ActivityThread.main(ActivityThread.java:6196) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:888) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:778) 
Caused by: java.lang.ClassNotFoundException: pl.droidsonroids.casty.CastOptionsProvider
at java.lang.Class.classForName(Native Method)
at java.lang.Class.forName(Class.java:400)
at java.lang.Class.forName(Class.java:326)
at com.google.android.gms.cast.framework.CastContext.zzbu(Unknown Source) 
at com.google.android.gms.cast.framework.CastContext.getSharedInstance(Unknown Source) 
at pl.droidsonroids.casty.a.(Unknown Source) 
at pl.droidsonroids.casty.a.a(Unknown Source) 
at com.creativetrends.simple.app.pro.main.VideoActivity.onCreate(Unknown Source) 
at android.app.Activity.performCreate(Activity.java:6698) 
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1140) 
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2643) 
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2755) 
at android.app.ActivityThread.-wrap12(ActivityThread.java) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1495) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:154) 
at android.app.ActivityThread.main(ActivityThread.java:6196) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:888) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:778) 
Caused by: java.lang.ClassNotFoundException: Didn't find class "pl.droidsonroids.casty.CastOptionsProvider" on path: DexPathList[[zip file "/data/app/com.creativetrends.simple.app.pro-2/base.apk"],nativeLibraryDirectories=[/data/app/com.creativetrends.simple.app.pro-2/lib/arm, /system/lib, /vendor/lib]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
at java.lang.ClassLoader.loadClass(ClassLoader.java:380)
at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
at java.lang.Class.classForName(Native Method) 
at java.lang.Class.forName(Class.java:400) 
at java.lang.Class.forName(Class.java:326) 
at com.google.android.gms.cast.framework.CastContext.zzbu(Unknown Source) 
at com.google.android.gms.cast.framework.CastContext.getSharedInstance(Unknown Source) 
at pl.droidsonroids.casty.a.(Unknown Source) 
at pl.droidsonroids.casty.a.a(Unknown Source) 
at com.creativetrends.simple.app.pro.main.VideoActivity.onCreate(Unknown Source) 
at android.app.Activity.performCreate(Activity.java:6698) 
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1140) 
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2643) 
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2755) 
at android.app.ActivityThread.-wrap12(ActivityThread.java) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1495) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:154) 
at android.app.ActivityThread.main(ActivityThread.java:6196) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:888) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:778) 

Custom headers

Can we send custom headers like authorization in casty to play hls m3u8?

How to Cast Youtube Video using Casty?

I found Casty during my search, I have a question, what If I would like to cast Youtube Video using Casty lib.

Here is the link of sample code, I am using to play Youtube video using API within my App... I want to cast same.

I believe it's not gonna take much time for you, so can you please write a separate method to cast Youtube Video in your MainActivity.java class. (I'm afraid, in this case we have Play/Pause already :) )

Can we use something like this, to work with Youtube videos:
return new MediaData.Builder("https://www.youtube.com/watch?v=RKjUPQCXnsM")

Shall we need to keep other variables same as you kept in createSampleMediaData() method and what are the areas where we need to make changes in our code... (in existing class)

custom Discovery mode

Hi,

I would like to customise the discovery mode when searching for available devices, at the moment when we tap the chromecast button, a menu gets inflated and we can see the available devices... I'd like to take the available devices and add them to a relative layout somewhere on my UI and then the user can interact with the devices by tapping on a recycler view item, where each recycler view item represents a device.

Can we do this with casty

thanks

Xamarin platform?

Hi!
This library sounds like a really good idea, but i'm coding in Xamarin and therefore i don't have the build.gradle, BUT I've read that i should still be able to use your library through some kind of a Bindings library which will convert the .Jar file to a C# file which i can initialize and then use its methods. But you only have .java files?
Maybe you can help me? I should be able to convert all of your .java files to one single .Jar file? :)
Hopefully you have time to help a student! :)

Memory Leak

Hey,
Great library, made life easier for me.
but, it has a memory leak when I use Casty.create(this).withMiniController() in my activity

unless I'm implementing the code wrongly?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.