Skip to content
Chromecast Client Library
Elixir Protocol Buffer
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
config
lib
proto
test
.gitignore
LICENSE.TXT
README.md
mix.exs
mix.lock

README.md

Chromecast

A library for controlling and monitoring a Chromecast. It currently only supports pause/play/volume, but also keeps track of the state of the device, such as media type, playback position, background images, etc. There is no support for queuing or playing new media files.

Installation

1. git clone https://github.com/NationalAssociationOfRealtors/chromecast.git
2. mix do deps.get, deps.compile
3. iex -S mix

Usage

iex(4)> {:ok, device} = Chromecast.start_link {192,168,1,138}
{:ok, #PID<0.225.0>}
Idle Screen with background images
iex(7)> Chromecast.state(device)
%Chromecast.State{destination_id: "web-5", ip: {192, 168, 1, 138},
 media_session: nil,
 media_status: %{"appDeviceId" => "BBC9E06BCA89EA246A21D650BE44BA52",
   "backendData" => "[\"https://lh3.googleusercontent.com/mij2Eglc324jD_kxhu43aSnX8w9Xfr7XQdEwLpWpiVoFWZSh8Ljj=s1920-w1920-h1080-p-k-no-nd-mv\",\"Justin Brown\",null,null,120,7,null,null,null,\"https://plus.google.com/photos/101005060236931055507/albums/5720519753508285169/6122212643311873906\",null,null,\"Photo by Justin Brown\",null,[[\"New York City, NY\",\"https://www.google.com/search?q=New+York+City%2C+New+York\"]],null,0,\"FEATURED_GPLUS_TITLE\",\"AF1QipPSuE14ATWH-FwoO3DGJyiyewcTORhjDEuFTF__\",null,null,0,null,null,null,46,[[46,\"FEATURED_GPLUS_TITLE\",\"Google+\"],[3,\"PHOTO_COMMUNITIES_TITLE\",\"Featured photos\"]],1293145096798261,[9700053]]",
   "numLinkedUsers" => 0, "requestId" => "0",
   "topicHistory" => ["[\"https://lh3.googleusercontent.com/proxy/GUfWvBxLY7h8Li2oVoqt5QMs8h6heAX-TTnlKUKND1JCbg2MKPD9yi1QzUXhp3oEWbpfkRp8MWRepmgYBMOm5vNn4O2F1XCCoWG37QCbweiYEJ8mTj_aknB0306wcWfqcSuo7gc6ZOdO2mOod9lnaX453YPntwNsNws4Ux_g=s1920-w1920-h1080-n-k-no-nd-mv\",null,null,null,120,11,null,null,null,\"https://500px.com/photo/105754217/gravity-chamber-by-alex-noriega?utm_source=google&utm_medium=chromecast&utm_campaign=september_launch\",null,null,\"Photo by Alex Noriega\",null,[],null,0,\"FEATURED_500PX_TITLE\",\"0312daec19f4b4cb0ccf374d83a605e3\",null,null,0,null,null,null,47,[[47,\"FEATURED_500PX_TITLE\",\"500px\"],[3,\"PHOTO_COMMUNITIES_TITLE\",\"Featured photos\"]],-7860625334833097,[9700053]]",
    "[\"https://lh3.googleusercontent.com/NcFlzZdTZazuc1FH1vuyExOFYMdz6rKtMrtdtghDJ_ScngVdnmWmgwxffJbyWRWfq-tvVFT5zZvtHWpeXvw=s1920-w1920-h1080-p-k-no-nd-mv\",\"Robin Griggs Wood\",null,null,120,7,null,null,null,\"https://plus.google.com/photos/103698889037599783920/albums/5893830837236231873/6286435320971968402\",null,null,\"Photo by Robin Griggs Wood\",null,[[\"Palace of Fine Arts, San Francisco, California\",\"https://www.google.com/search?q=Palace+of+Fine+Arts%2C+San+Francisco\"]],null,0,\"FEATURED_GPLUS_TITLE\",\"AF1QipMKwdLuP0T3JWxRBCBiDGJxXNmSxTOIaAHM7Gxe\",null,null,0,null,null,null,46,[[46,\"FEATURED_GPLUS_TITLE\",\"Google+\"],[3,\"PHOTO_COMMUNITIES_TITLE\",\"Featured photos\"]],5097477668030082,[9700053]]",
    "[\"https://lh5.googleusercontent.com/proxy/vkAEc_MrmRauQq8jR40hx_yh-ExzYSupzCaA3uKbLv6MKhRFd4tit_f1CTneIYHT7vYkgbPANzXQ0vuYzXm1WLpUyTFHv0Vcj13gH9Ibr_z9AJR0SrTQ2hmfXz7isqP_EhXtk9-ldjRQOhhc5n1waAu8IXtiid5Pt5ZYbNE2oooJysxGh8-2vprNq3yArVBNC-DWdvzEjaJoR_wfkdSGWG2houxsQzAG6ZgInJDJ1cz0U1_a8tdTStJ56CoTMAs=s1920-w1920-h1080-p-k-no-nd-mv\",null,null,null,120,11,null,null,null,\"http://www.gettyimages.com/detail/photo/suspension-bridge-royalty-free-image/107709060?esource=chromecast\",null,null,\"Photo by Daniel Muller\",null,[],null,0,\"FEATURED_GETTYIMAGES_TITLE\",\"89ae3a3b697da2318e0a9fbd8951b7d5\",null,null,0,null,null,null,48,[[48,\"FEATURED_GETTYIMAGES_TITLE\",\"Getty Images\"],[3,\"PHOTO_COMMUNITIES_TITLE\",\"Featured photos\"]],3037105898765724,[9700053]]",
    "[\"https://lh3.googleusercontent.com/SxgLlfCrzM66njIgpKlq2nkRrCdq2_sONwQDxl0AAImggIso_VkVzg=s1920-w1920-h1080-p-k-no-nd-mv\",\"Saurabh Paranjape\",null,null,120,7,null,null,null,\"https://plus.google.com/photos/105737724482908033948/albums/6213733340481709841/6213733341343554690\",null,null,\"Photo by Saurabh Paranjape\",null,[[\"Westminster Bridge, London, England\",\"https://www.google.com/search?q=Westminster+Bridge\"]],null,0,\"FEATURED_GPLUS_TITLE\",\"AF1QipN2LkA4gtWKmP4xk7RWQFR9IKB9EnW2m4s3qVsp\",null,null,0,null,null,null,46,[[46,\"FEATURED_GPLUS_TITLE\",\"Google+\"],[3,\"PHOTO_COMMUNITIES_TITLE\",\"Featured photos\"]],-6380615397988733,[9700053]]",
    "[\"https://lh3.googleusercontent.com/mij2Eglc324jD_kxhu43aSnX8w9Xfr7XQdEwLpWpiVoFWZSh8Ljj=s1920-w1920-h1080-p-k-no-nd-mv\",\"Justin Brown\",null,null,120,7,null,null,null,\"https://plus.google.com/photos/101005060236931055507/albums/5720519753508285169/6122212643311873906\",null,null,\"Photo by Justin Brown\",null,[[\"New York City, NY\",\"https://www.google.com/search?q=New+York+City%2C+New+York\"]],null,0,\"FEATURED_GPLUS_TITLE\",\"AF1QipPSuE14ATWH-FwoO3DGJyiyewcTORhjDEuFTF__\",null,null,0,null,null,null,46,[[46,\"FEATURED_GPLUS_TITLE\",\"Google+\"],[3,\"PHOTO_COMMUNITIES_TITLE\",\"Featured photos\"]],1293145096798261,[9700053]]"]},
 receiver_status: %{"requestId" => 1,
   "status" => %{"applications" => [%{"appId" => "E8C28D3C",
        "displayName" => "Backdrop", "isIdleScreen" => true,
        "namespaces" => [%{"name" => "urn:x-cast:com.google.cast.sse"},
         %{"name" => "urn:x-cast:com.google.cast.inject"}],
        "sessionId" => "C6591D59-64B2-4357-98DE-A982A75FAA6F",
        "statusText" => "", "transportId" => "web-5"}],
     "volume" => %{"controlType" => "attenuation", "level" => 1.0,
       "muted" => false, "stepInterval" => 0.05000000074505806}},
   "type" => "RECEIVER_STATUS"}, request_id: 4,
 session: "C6591D59-64B2-4357-98DE-A982A75FAA6F",
 ssl: {:sslsocket, {:gen_tcp, #Port<0.7995>, :tls_connection, :undefined},
  #PID<0.226.0>}}
Youtube Video playing
  iex(126)> Chromecast.state(device)
%Chromecast.State{destination_id: "web-13", ip: {192, 168, 1, 138},
 media_session: 1936679159,
 media_status: %{"appDeviceId" => "BBC9E06BCA89EA246A21D650BE44BA52",
   "backendData" => "[\"https://lh4.googleusercontent.com/proxy/c5GLPnubdevNNbhBlOekeEAA64Us7uNSMJkhgjWZlCQIo1eqqwXve4RZlIcBQwahoEI32MXkXXOhZmFWayEpF-UJafokwVKemB2EWX42dJDUi6xCLmPYLRDEmZ5YPCDefGJikV2XgR8e9pE5b4XS215Bygf6t-oNSTK-Ae_uKtKq3gOMvFt7PmmFPj9uvqjCu9N1ehUQ6CXiH7Ke7z6nqpO5dW6kfDVvdAV1oEtl6bD572C1QHWaD5d9HKnRzx-l0j4CryxMq0xIODl2ziPasNGGe4zHCYpGXIzq7qrF=s1920-w1920-h1080-fcrop64=1,0000170affffef93-k-no-nd-mv\",null,null,null,120,11,null,null,null,\"http://www.gettyimages.com/detail/photo/grand-prismatic-spring-yellowstone-national-high-res-stock-photography/462556881?esource=chromecast\",null,null,\"Photo by Peter Adams\",null,[],null,0,\"FEATURED_GETTYIMAGES_TITLE\",\"363fad4f1769ed622205dc4e1b75281a\",null,null,0,null,null,null,48,[[48,\"FEATURED_GETTYIMAGES_TITLE\",\"Getty Images\"],[3,\"PHOTO_COMMUNITIES_TITLE\",\"Featured photos\"]],4718130360558134,[9700053]]",
   "currentTime" => 0.453, "customData" => %{"playerState" => 1},
   "media" => %{"contentId" => "RuWRnIAwPIU",
     "contentType" => "x-youtube/video",
     "customData" => %{"currentIndex" => 2,
       "listId" => "RQAGdO5p9nVvzfKwZGP9XUYZDXbqcljCV01fxpzRs0Qpu0d_ZPowkJ508lgJyOldy_hFam51_fF_NieXwcngOoZlXYeR89R8CXAMGvyLvP82nkOuUUAVbL1hQ"},
     "duration" => 157.314693877551,
     "metadata" => %{"images" => [%{"url" => "https://i.ytimg.com/vi/RuWRnIAwPIU/hqdefault.jpg"}],
       "metadataType" => 0,
       "title" => "Metropolis 80 Freeskate Vs Barcelona - Powerslide"},
     "streamType" => "BUFFERED"}, "mediaSessionId" => 1936679159,
   "numLinkedUsers" => 0, "playbackRate" => 1, "playerState" => "PLAYING",
   "requestId" => "0", "supportedMediaCommands" => 3,
   "topicHistory" => ["[\"https://lh5.googleusercontent.com/proxy/vkAEc_MrmRauQq8jR40hx_yh-ExzYSupzCaA3uKbLv6MKhRFd4tit_f1CTneIYHT7vYkgbPANzXQ0vuYzXm1WLpUyTFHv0Vcj13gH9Ibr_z9AJR0SrTQ2hmfXz7isqP_EhXtk9-ldjRQOhhc5n1waAu8IXtiid5Pt5ZYbNE2oooJysxGh8-2vprNq3yArVBNC-DWdvzEjaJoR_wfkdSGWG2houxsQzAG6ZgInJDJ1cz0U1_a8tdTStJ56CoTMAs=s1920-w1920-h1080-p-k-no-nd-mv\",null,null,null,120,11,null,null,null,\"http://www.gettyimages.com/detail/photo/suspension-bridge-royalty-free-image/107709060?esource=chromecast\",null,null,\"Photo by Daniel Muller\",null,[],null,0,\"FEATURED_GETTYIMAGES_TITLE\",\"89ae3a3b697da2318e0a9fbd8951b7d5\",null,null,0,null,null,null,48,[[48,\"FEATURED_GETTYIMAGES_TITLE\",\"Getty Images\"],[3,\"PHOTO_COMMUNITIES_TITLE\",\"Featured photos\"]],3037105898765724,[9700053]]",
    "[\"https://lh3.googleusercontent.com/SxgLlfCrzM66njIgpKlq2nkRrCdq2_sONwQDxl0AAImggIso_VkVzg=s1920-w1920-h1080-p-k-no-nd-mv\",\"Saurabh Paranjape\",null,null,120,7,null,null,null,\"https://plus.google.com/photos/105737724482908033948/albums/6213733340481709841/6213733341343554690\",null,null,\"Photo by Saurabh Paranjape\",null,[[\"Westminster Bridge, London, England\",\"https://www.google.com/search?q=Westminster+Bridge\"]],null,0,\"FEATURED_GPLUS_TITLE\",\"AF1QipN2LkA4gtWKmP4xk7RWQFR9IKB9EnW2m4s3qVsp\",null,null,0,null,null,null,46,[[46,\"FEATURED_GPLUS_TITLE\",\"Google+\"],[3,\"PHOTO_COMMUNITIES_TITLE\",\"Featured photos\"]],-6380615397988733,[9700053]]",
    "[\"https://lh3.googleusercontent.com/mij2Eglc324jD_kxhu43aSnX8w9Xfr7XQdEwLpWpiVoFWZSh8Ljj=s1920-w1920-h1080-p-k-no-nd-mv\",\"Justin Brown\",null,null,120,7,null,null,null,\"https://plus.google.com/photos/101005060236931055507/albums/5720519753508285169/6122212643311873906\",null,null,\"Photo by Justin Brown\",null,[[\"New York City, NY\",\"https://www.google.com/search?q=New+York+City%2C+New+York\"]],null,0,\"FEATURED_GPLUS_TITLE\",\"AF1QipPSuE14ATWH-FwoO3DGJyiyewcTORhjDEuFTF__\",null,null,0,null,null,null,46,[[46,\"FEATURED_GPLUS_TITLE\",\"Google+\"],[3,\"PHOTO_COMMUNITIES_TITLE\",\"Featured photos\"]],1293145096798261,[9700053]]",
    "[\"https://lh3.googleusercontent.com/LEwrbgnOQd-jBz6s5FuTqtKlUaa_UExFsBLBlzOi0rtsopryVScqkQ=s1920-w1920-h1080-p-k-no-nd-mv\",\"Aaron Choi\",null,null,120,7,null,null,null,\"https://plus.google.com/photos/111628818598106803270/albums/6117592132440816289/6140512115181587250\",null,null,\"Photo by Aaron Choi\",null,[[\"Manarola, Cinque Terre, Italy\",\"https://www.google.com/search?q=Manarola+in+Cinque+Terre%2C+Italy\"]],null,0,\"FEATURED_GPLUS_TITLE\",\"AF1QipNQEjzYMlvgXzfQkE6l9Yrsip6SGFnuQim2xlcY\",null,null,0,null,null,null,46,[[46,\"FEATURED_GPLUS_TITLE\",\"Google+\"],[3,\"PHOTO_COMMUNITIES_TITLE\",\"Featured photos\"]],7159867778728899,[9700053]]",
    "[\"https://lh4.googleusercontent.com/proxy/c5GLPnubdevNNbhBlOekeEAA64Us7uNSMJkhgjWZlCQIo1eqqwXve4RZlIcBQwahoEI32MXkXXOhZmFWayEpF-UJafokwVKemB2EWX42dJDUi6xCLmPYLRDEmZ5YPCDefGJikV2XgR8e9pE5b4XS215Bygf6t-oNSTK-Ae_uKtKq3gOMvFt7PmmFPj9uvqjCu9N1ehUQ6CXiH7Ke7z6nqpO5dW6kfDVvdAV1oEtl6bD572C1QHWaD5d9HKnRzx-l0j4CryxMq0xIODl2ziPasNGGe4zHCYpGXIzq7qrF=s1920-w1920-h1080-fcrop64=1,0000170affffef93-k-no-nd-mv\",null,null,null,120,11,null,null,null,\"http://www.gettyimages.com/detail/photo/grand-prismatic-spring-yellowstone-national-high-res-stock-photography/462556881?esource=chromecast\",null,null,\"Photo by Peter Adams\",null,[],null,0,\"FEATURED_GETTYIMAGES_TITLE\",\"363fad4f1769ed622205dc4e1b75281a\",null,null,0,null,null,null,48,[[48,\"FEATURED_GETTYIMAGES_TITLE\",\"Getty Images\"],[3,\"PHOTO_COMMUNITIES_TITLE\",\"Featured photos\"]],4718130360558134,[9700053]]"],
   "volume" => %{"level" => 1, "muted" => false}},
 receiver_status: %{"requestId" => 12,
   "status" => %{"applications" => [%{"appId" => "233637DE",
        "displayName" => "YouTube", "isIdleScreen" => false,
        "namespaces" => [%{"name" => "urn:x-cast:com.google.youtube.mdx"},
         %{"name" => "urn:x-cast:com.google.cast.media"},
         %{"name" => "urn:x-cast:com.google.cast.cac"},
         %{"name" => "urn:x-cast:com.google.cast.inject"}],
        "sessionId" => "9F2318D0-8581-446E-9BFB-AA8FDABD74F4",
        "statusText" => "YouTube", "transportId" => "web-13"}],
     "volume" => %{"controlType" => "attenuation", "level" => 1.0,
       "muted" => false, "stepInterval" => 0.05000000074505806}},
   "type" => "RECEIVER_STATUS"}, request_id: 39,
 session: "9F2318D0-8581-446E-9BFB-AA8FDABD74F4",
 ssl: {:sslsocket, {:gen_tcp, #Port<0.7995>, :tls_connection, :undefined},
  #PID<0.226.0>}}

Explanation

Chromecast.start_link(ip \\ {192, 168, 1, 15}) starts a GenServer that opens a binary SSL connection to the Chromecast. The protocol is based on Protobufs, and uses the exprotobuf library. Every few seconds the Chromecast will send out a ping request and expects a pong within a few seconds, otherwise it closes the session. Periodically Chromecast sends a request with it's current state, this is captured by the Chromecast process and it's state is updated. To pause media call Chromecast.pause(:device) where device is the PID returned when calling Chromecast.start_link. Play is similar Chromecast.play(:device). You can easily connect to multiple Chromecasts by calling Chromecast.start_link(ip) with unique IP addresses. You can discover your Chromecast(s) using mDNS and/or SSDP.

You can’t perform that action at this time.