Google cast: How to show metadata in default media player? - google-chrome

I am trying to make my chrome sender application send metadata to the default media receiver application but the default media receiver does not show the metadata. I cannot find documentation or examples. Does anybody know how implement this? Below code plays the audio but the player does not show any image or other metadata.
Initialization:
var sessionRequest = new chrome.cast.SessionRequest(chrome.cast.media.DEFAULT_MEDIA_RECEIVER_APP_ID);
var apiConfig = new chrome.cast.ApiConfig(sessionRequest,
sessionListener,
receiverListener);
chrome.cast.initialize(apiConfig, onInitSuccess, onError);
chrome.cast.requestSession(onRequestSessionSuccess, onLaunchError);
...
Loading media
url = "url-to-media"
var mediaInfo = new chrome.cast.media.MediaInfo(url, 'audio/aac');
mediaInfo.metadata = new chrome.cast.media.MusicTrackMediaMetadata()
mediaInfo.metadata.albumName = 'This is the name of the album'
mediaInfo.metadata.artistName = 'This is the name of the artist'
mediaInfo.metadata.songName = 'This is the name of the song'
im = chrome.cast.Image('http://m1.behance.net/rendition/modules/575407/disp/822271229466847.png')
mediaInfo.metadata.images = new Array(im)
var request = new chrome.cast.media.LoadRequest(mediaInfo);
session.loadMedia(request,onMediaDiscovered.bind(this, 'loadMedia'), onMediaError())

Try this -
mediaInfo.metadata.title = 'This is the name of the song';
mediaInfo.metadata.subtitle = 'This is the name of the artist';

We've just released a Cast extension Beta that has fixed this issue. See this announcement: https://plus.google.com/+ShawnShen/posts/aVXSHyceNbR.
I also added a project on github that provides sample code at:
https://github.com/googlecast/CastMedia-chrome

Currently the default media receiver app accepts certain metadata fields. Detailed specs are given here: https://developers.google.com/cast/docs/reference/messages.
For the MusicTrackMediaMetaData type, be sure to set metadataType to 3. The following snippet works.
mediaInfo.metadata = new chrome.cast.media.MusicTrackMediaMetadata()
mediaInfo.metadata.metadataType = 3;
mediaInfo.metadata.title = 'This is the name of the title';
mediaInfo.metadata.albumArtist = 'This is the name of the album artist';
mediaInfo.metadata.artist = 'This is the name of the artist';
mediaInfo.metadata.albumName = 'This is the name of the album';
//mediaInfo.metadata.composer = 'composer';
//mediaInfo.metadata.trackNumber = 13;
//mediaInfo.metadata.discNumber = 2;
mediaInfo.metadata.releaseDate = '2011';
mediaInfo.metadata.images = [{'url': 'http://m1.behance.net/rendition/modules/575407/disp/822271229466847.png'}];
var request = new chrome.cast.media.LoadRequest(mediaInfo);
session.loadMedia(request, onMediaDiscovered.bind(this, 'loadMedia'), onMediaError());
A bug has been filed to fix some mismatch between Chrome Sender SDK and default receiver app.
You can always do your own custom receiver app and add your own custom data like the following.
var mediaInfo = new chrome.cast.media.MediaInfo(url, 'audio/mp3');
var request = new chrome.cast.media.LoadRequest(mediaInfo);
var payload = {
"albumName": 'This is the name of the album',
"songName": 'This is the name of the song',
"thumb": 'http://m1.behance.net/rendition/modules/575407/disp/822271229466847.png',
"artistName": 'This is the name of the artist'
};
var json = {
"payload": payload
};
request.customData = json;

Related

Sending data to a JSON with AS3

I've asked my client to share his database login and password but he can't give me full access to his database (security reason I suppose).
He told me to use a REST/JSON service that allows to post the data via this url with a specific key that allows him to identify all the datas coming from my app.
Here's what I did :
var urlRequest:URLRequest = new URLRequest("the_url_using JSON service");
urlRequest.method = URLRequestMethod.POST;
var urlvars: URLVariables = new URLVariables;
urlvars.observer_name = "Test Coco";
urlvars.observation_number = "5433";
trace("urlvars = "+urlvars);
urlRequest.data = urlvars;
var urlLoader:URLLoader = new URLLoader();
urlLoader.addEventListener(Event.COMPLETE, onComplete);
urlLoader.load(urlRequest);
It's working, as it's sending the data, but the data format seems to be incorrect..
the url returns this error : "Observer name is Missing"
And the "trace (urlvars)" output :
urlvars = observer%5Fname=Test%20Coco&observation%5Fnumber=5433
So I think the problem come from the special character or something like that (as you can "observer_name" results by "observer%5Fname" and we can see a lot of %5")
Any idea how can I solve this ?
JSON string is a string representation of a generic object. Basically you go:
var anObject:Object =
{
"observer_name": "Test Coco",
"observation_number": 5433
};
or you can construct it
var anObject:Object = new Object;
anObject['observer_name'] = "Test Coco";
anObject['observation_number'] = 5433;
and then you convert it to String and attach to request
var jsonString:String = JSON.stringify(anObject);
urlRequest.method = URLRequestMethod.POST;
urlRequest.data = jsonString;
Read more about it: https://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/JSON.html
Keep in mind that I don't know the specifics of that REST server of yours and the code above just might not work as it is. I only explain how to send a JSON string as a POST request.

Adobe AIR file upload response data in complete handler is null while fiddler(web debugger) shows that json is returned as response

When uploading a file from adobe AIR to a backbone server, the response returned is not anyway accessible when using file.upload(request) function, while i can see json response in fiddler(web debugger and in task manager), also it was working fine when using URLLoader.load() instead of file.upload()
var url = "api url of backbone server ";
request = null;
file = null;
request = new air.URLRequest(url);
request.useCache = false;
var authorization = new air.URLRequestHeader("Authorization", "Bearer "+accessToken);
var contentType = new air.URLRequestHeader("Content-Type", "multipart/form-data; boundary=" + boundary);
var Accept = new air.URLRequestHeader("Accept", "application/json;charset=UTF-8");
request.requestHeaders.push(authorization);
request.requestHeaders.push(contentType);
request.requestHeaders.push(Accept);
file = new air.File(path);
pathNative = file.nativePath;
var directory = getDirectoryFromPath(pathNative);
params = new air.URLVariables();
params.parent_id = directory.directory_id;
params.name = file.name;
request.data = params;
request.method = air.URLRequestMethod.POST;
request.contentType = 'multipart/form-data, boundary='+boundary;
var file = new air.File(path);
file.upload(request);
file.addEventListener(air.Event.COMPLETE, function(e){
air.Introspector.Console.log(file);
air.Introspector.Console.log(e);
air.Introspector.Console.log(e.target.data);
});
This is the console for complete event as you can see returned data is null.
see console
while in fiddler shows that json is returned.
see fiddler
Seems like it's a known issue on iOS? Are you trying to do this from iOS?
https://forums.adobe.com/thread/1720117?start=0&tstart=0
I ran into the same problem. Instead of using air.Event.COMPLETE, try to use air.DataEvent.UPLOAD_COMPLETE_DATA:
file.addEventListener(air.DataEvent.UPLOAD_COMPLETE_DATA, function(e){
air.Introspector.Console.log(e.data);
});

gsutil on a Google Compute Engine VM can't use service account authentication with a key file

I'm launching an instance from the google .net API and despite my best efforts I can't get it to copy anything to or from storage. Currently I'm authenticating with a developer console service account like this:-
string ServiceAccountEmail = "blahblah#developer.gserviceaccount.com";
var certificate = new X509Certificate2(#"key.p12", "notasecret", X509KeyStorageFlags.Exportable);
ServiceAccountCredential credential = new ServiceAccountCredential(
new ServiceAccountCredential.Initializer(ServiceAccountEmail)
{
Scopes = new[] { ComputeService.Scope.Compute, ComputeService.Scope.DevstorageFullControl }
}.FromCertificate(certificate));
var cs = new ComputeService(new BaseClientService.Initializer
{
ApplicationName = "appname",
HttpClientInitializer = (Google.Apis.Http.IConfigurableHttpClientInitializer)credential,
});
Google.Apis.Compute.v1.Data.Instance newinst = new Google.Apis.Compute.v1.Data.Instance();
newinst.Name = "generatedinstance";
newinst.MachineType = "https://www.googleapis.com/compute/v1/projects/projectid/zones/zone/machineTypes/n1-standard-1";
Google.Apis.Compute.v1.Data.AttachedDisk ad = new Google.Apis.Compute.v1.Data.AttachedDisk();
ad.AutoDelete = true;
ad.Boot = true;
ad.Type = "PERSISTENT";
ad.InitializeParams = new Google.Apis.Compute.v1.Data.AttachedDiskInitializeParams();
ad.InitializeParams.DiskName = "newdisk";
ad.InitializeParams.SourceImage = "https://www.googleapis.com/compute/v1/projects/projectid/global/images/customimage";
ad.InitializeParams.DiskType = "https://www.googleapis.com/compute/v1/projects/projectid/zones/zone/diskTypes/pd-standard";
ad.Mode = "READ_WRITE";
newinst.Disks = new List<Google.Apis.Compute.v1.Data.AttachedDisk>();
newinst.Disks.Add(ad);
Google.Apis.Compute.v1.Data.NetworkInterface ni = new Google.Apis.Compute.v1.Data.NetworkInterface();
ni.Network = "https://www.googleapis.com/compute/v1/projects/projectid/global/networks/default";
ni.AccessConfigs = new List<Google.Apis.Compute.v1.Data.AccessConfig>();
ni.AccessConfigs.Add(new Google.Apis.Compute.v1.Data.AccessConfig
{
Type = "ONE_TO_ONE_NAT",
Name = "External NAT",
});
newinst.NetworkInterfaces = new List<Google.Apis.Compute.v1.Data.NetworkInterface>();
newinst.NetworkInterfaces.Add(ni);
var start = new Google.Apis.Compute.v1.Data.Metadata.ItemsData();
start.Key = "startup-script";
start.Value = "*startup script* includes gsutil cp which won't work without service account attached";
newinst.Metadata = new Google.Apis.Compute.v1.Data.Metadata();
newinst.Metadata.Kind = "compute#metadata";
newinst.Metadata.Items = new List<Google.Apis.Compute.v1.Data.Metadata.ItemsData>();
newinst.Metadata.Items.Add(start);
newinst.ServiceAccounts = new List<Google.Apis.Compute.v1.Data.ServiceAccount>();
//var sa = new Google.Apis.Compute.v1.Data.ServiceAccount();|with this section
//sa.Email = "blahblah#developer.gserviceaccount.com"; |the instance won't
//sa.Scopes = new[] { ComputeService.Scope.Compute, |start. (An equivalent
ComputeService.Scope.DevstorageFullControl }; |is found in instance
//newinst.ServiceAccounts.Add(sa); |start REST request)
var instinsert = new InstancesResource.InsertRequest(cs, newinst, "projectid", "zone");
var insertresponse = instinsert.Execute();
The message I get when I try to use gsutil cp is "You do not currently have an active account selected.". Can anyone tell me where I'm going wrong?
You need to run gcloud auth activate-service-account blahblah#developer.gserviceaccount.com --key-file path_to_key.p12 to tell the Cloud SDK (including gsutil) about your service account.
As per the code provided, I can see that the original example has
var certificate = new X509Certificate2(#"key.p12", "notasecret", X509KeyStorageFlags.Exportable);
I notice you are missing the '#'in your code. I'm not very familiar with .Net. I have tested these examples in python and this one. When creating my instance I added the service account for GCS and the file is uploaded correctly.
OKAY! Problem solved. The part I was getting wrong was the bit commented out in the question-
var sa = new Google.Apis.Compute.v1.Data.ServiceAccount();
sa.Email = "blahblah#developer.gserviceaccount.com";
sa.Scopes = new[] { ComputeService.Scope.Compute,
ComputeService.Scope.DevstorageFullControl };
newinst.ServiceAccounts.Add(sa);
I needed the email for the main service account for the developer console in this section rather than the same service account I used to create the credentials but don't ask me why. Point is the instance launches and gsutil is now happily copying away.
Thanks for your time and help everyone!
Ross

Extracting metadata object from MediaElement (AS3)

I am attempting to retrieve metadata from a URLResource. The URLResource is not controlled by me, but passed into a function that I am using.
The URLResource is created like this:
var resource:URLResource = new URLResource("http://mediapm.edgesuite.net/osmf/content/test/logo_animated.flv");
// Add Metadata for the URLResource
var VideoParams:Object = {
Name:"Logo Video",
Owner:"Self",
Duration:"1:25:20",
category:"education"
}
resource.addMetadataValue("VideoParams", VideoParams);
var media:MediaElement = factory.createMediaElement(resource);
Now the URLResource contains the metadata. I will recieve a MediaElement resource. How do I extract the metadata back?
Here's what the debugger shows (media is a MediaElement object containing the URLResource w/ metadata) :
fdb>print media.resource.
$1 = [Object 246396705, class='org.osmf.media::URLResource']
_mediaType = null
_metadata = [Object 416970209, class='flash.utils::Dictionary']
_mimeType = null
url = "http://mediapm.edgesuite.net/osmf/content/test/logo_animated.flv"
fdb>print media.resource._metadata.
$2 = metadata = [Object 416970209, class='flash.utils::Dictionary']
VideoParams = [Object 416970305, class='Object']
(fdb)print media.resource._metadata.VideoParams.
$3 = VideoParams = [Object 416970305, class='Object']
category = "education"
Duration = "1:25:20"
Owner = "Self"
Name = "Logo Video"
I've attempted extracting the metadata object with:
media.resource.getMetadata("VideoParams");
and a host of other attempts, but can't figure out how to get at that darned metadata.
Any thoughts greatly appreciated!
This actually turned out to be pretty easy...just needed to use the getMetadataValue function in the URLResource object like this:
var temp:Object = media.resource.getMetadataValue("VideoParams");
trace('Owner:', temp.Owner);

Using yfrog's uploadAndPost with Actionscript/Adobe AIR

I am trying to upload a photo from an Adobe AIR application to yfrog's api, http://code.google.com/p/imageshackapi/wiki/YFROGuploadAndPost. I have the following code:
public function upload(file:File, msg:String, username:String, password:String):void {
var vars:URLVariables = new URLVariables();
vars["username"] = username;
vars["password"] = password;
vars["public"] = "yes";
vars["key"] = API_KEY; //API_KEY is a constant string that holds my developer key
vars["message"] = msg;
var request:URLRequest = new URLRequest("http://yfrog.com/api/uploadAndPost");
request.method = URLRequestMethod.POST;
request.contentType = "multipart/form-data";
request.data = vars;
file.upload(request, "media");
}
When I run this code, yfrog returns 404 status. This seems to only happen if I do a media file upload with the api. If I use a "url" upload to the same api url - everything works. Has anyone else gotten a "media" file upload to work? If so, how would you change the code?
Looks like that API has been replaced as of today with the OAuth Echo method
http://code.google.com/p/imageshackapi/wiki/TwitterAuthentication