I'm developing a video application with HLS streams.
These streams can only be played if I send in the request https custom headers.
On iOS I do like this:
NSMutableDictionary* headers = [NSMutableDictionary dictionary];
[headers setObject:#"MY_VALUE" forKey:#"MY_KEY"];
AVURLAsset* asset = [AVURLAsset URLAssetWithURL:videoTempURL options:#{#"AVURLAssetHTTPHeaderFieldsKey": headers}];
AVPlayerItem *myNewitem = [[AVPlayerItem alloc] initWithAsset:asset];
and on android like this:
DefaultHttpDataSource.Factory MGSource = new DefaultHttpDataSourceFactory(Util.getUserAgent( MainActivity.getContext(), "MY_USER_AGENT"), BANDWIDTH_METER);
MGSource.getDefaultRequestProperties().set("MY_KEY", "MY_VALUE");
and these methods work very well.
And I want to send these feeds on a ChromeCast.
So I look at how to do on Google Doc and they say this in receiver :
in this function :
sampleplayer.CastPlayer.prototype.loadVideo_ = function(info) {
this.log_('loadVideo_');
var self = this;
var protocolFunc = null;
var url = info.message.media.contentId;
...
host.updateSegmentRequestInfo = function(requestInfo) {
// example of setting CORS withCredentials
requestInfo.withCredentials = true;
// example of setting headers
//requestInfo.headers = {};
//requestInfo.headers['content-type'] = 'text/xml;charset=utf-8';
requestInfo.headers['MY_KEY'] = 'MY_VALUE';
console.log("################# SENDING HEADERS");
};
host.updateManifestRequestInfo = function(requestInfo) {
if (!requestInfo.url) {
requestInfo.url = this.url;
}
requestInfo.withCredentials = true;
};
host.updateLicenseRequestInfo = function(requestInfo) {
requestInfo.withCredentials = true;
};
But that does not work, can someone tell me how I can send custom headers in a URL to a ChromeCast.
Either in the Android sender or in the receiver.
thank you so much
Related
What would be best way to measure data usage in Android Xamarin app in Visual Studio?
I would like to know, how much data was transferred for each called request.
I was looking in Xamarin Profiler but there isn't any info about data usage.
Thanks.
One approach that you could use is via Android Device Monitor to watch network traffic
Alternatively you could wrap your request if you are using HttpClient in a custom handler and log the size of the request payload:
public class RequestLoggerHandler : HttpClientHandler
{
#if DEBUG
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
var stopwatch = Stopwatch.StartNew();
HttpResponseMessage response = null;
var headers = request.Headers;
var responseString = string.Empty;
var requestString = string.Empty;
var outputStringBuilder = new StringBuilder();
const string LINE_ENDING = "===================================================================================================";
const string SECTION_ENDING = "---------------------------------------------------------------------------------------------------";
try
{
if (request.Content != null) requestString = await request.Content?.ReadAsStringAsync();
response = await base.SendAsync(request, cancellationToken);
responseString = await response.Content?.ReadAsStringAsync();
outputStringBuilder.AppendLine(LINE_ENDING);
// Headers
outputStringBuilder.AppendLine("REQUEST HEADERS:");
foreach (var header in headers)
outputStringBuilder.AppendLine($"HEADER: {header.Key}: {header.Value?.ToList()?.FirstOrDefault()}");
outputStringBuilder.AppendLine(SECTION_ENDING);
// Parameters
outputStringBuilder.AppendLine("REQUEST PARAMS:");
outputStringBuilder.AppendLine(requestString);
outputStringBuilder.AppendLine(SECTION_ENDING);
// Response
outputStringBuilder.AppendLine("RESPONSE:");
outputStringBuilder.AppendLine(responseString);
outputStringBuilder.AppendLine(SECTION_ENDING);
return response;
}
finally
{
stopwatch.Stop();
var totalSize = 0L;
if (response != null)
{
var bodylength = response.Content.Headers.ContentLength;
var headerlength = response.Headers.ToString().Length;
totalSize = bodylength.GetValueOrDefault() + headerlength;
}
outputStringBuilder.AppendLine(string.Format("REQUEST [{0}:{1}] Time:{2}| Size:{3}| HTTP-CODE:{4}",
request.Method.ToString(),
request.RequestUri,
stopwatch.Elapsed.ToString("ss\\.fff"),
totalSize.ToPrettyByteSize(),
response?.StatusCode.ToString() ?? "No Internet Connectivity"));
outputStringBuilder.AppendLine(LINE_ENDING);
Debug.WriteLine("\n" + outputStringBuilder);
}
}
#endif
}
Then in your output window using VSColorOutput extension it produces a nice readable report of your request/response, including time and size. You can of cause simplify this code if all you are after is just the request/response size.
Here says the Web audio API works in Chrome for Android, and here I have tested CM Browser, Chrome and CyanogenMod default Android 5.1.1 browsers, and all pass the tests (specially the biquadNode one).
But When I open this codepen with an eq (biquadNode), I can hear the music but not the eq working.
Does biquadNode works in android? any special implementation is needed?
*Code pen required to post
var context = new AudioContext();
var mediaElement = document.getElementById('player');
var sourceNode = context.createMediaElementSource(mediaElement);
// EQ Properties
//
var gainDb = -40.0;
var bandSplit = [360,3600];
var hBand = context.createBiquadFilter();
hBand.type = "lowshelf";
hBand.frequency.value = bandSplit[0];
hBand.gain.value = gainDb;
var hInvert = context.createGain();
hInvert.gain.value = -1.0;
var mBand = context.createGain();
var lBand = context.createBiquadFilter();
lBand.type = "highshelf";
lBand.frequency.value = bandSplit[1];
lBand.gain.value = gainDb;
var lInvert = context.createGain();
lInvert.gain.value = -1.0;
sourceNode.connect(lBand);
sourceNode.connect(mBand);
sourceNode.connect(hBand);
hBand.connect(hInvert);
lBand.connect(lInvert);
hInvert.connect(mBand);
lInvert.connect(mBand);
var lGain = context.createGain();
var mGain = context.createGain();
var hGain = context.createGain();
lBand.connect(lGain);
mBand.connect(mGain);
hBand.connect(hGain);
var sum = context.createGain();
lGain.connect(sum);
mGain.connect(sum);
hGain.connect(sum);
sum.connect(context.destination);
// Input
//
function changeGain(string,type)
{
var value = parseFloat(string) / 100.0;
switch(type)
{
case 'lowGain': lGain.gain.value = value; break;
case 'midGain': mGain.gain.value = value; break;
case 'highGain': hGain.gain.value = value; break;
}
}
createMediaElementSource in Chrome on Android doesn't work in general. But if you have a recent build of Chrome (49 and later?), you can go to chrome://flags and enable the unified media pipeline option. That will make createMediaElementSource work like on desktop.
I developed an app in Windows phone 8/8.1, now I am trying to develop for android users. I am getting data from a website and displaying in my app. the website needs login userid,password. I successfully implemented it in C#. but I am unable to do it in java. can some guide me.
My code in C# :
HttpClientHandler handler = new HttpClientHandler();
HttpClient client = new HttpClient(handler, false);
handler.AllowAutoRedirect = true;
handler.PreAuthenticate = true;
Uri vceURI = new Uri("http://xxxx/default.aspx");
var html = await client.GetStringAsync(siteURI);
var doc = new HtmlAgilityPack.HtmlDocument();
doc.LoadHtml(html);
var viewstateNode = doc.GetElementbyId("__VIEWSTATE");
var eventvalidationNode = doc.GetElementbyId("__EVENTVALIDATION");
var viewstate = viewstateNode.GetAttributeValue("value", "");
var eventvalidation = eventvalidationNode.GetAttributeValue("value", "");
var formContent1 = new FormUrlEncodedContent(new[]
{
new KeyValuePair<string, string>("__VIEWSTATE", viewstate),
new KeyValuePair<string, string>("__EVENTVALIDATION", eventvalidation),
new KeyValuePair<string,string>("txtLoginID",_username),
new KeyValuePair<string,string>("txtPWD",_pswd),
new KeyValuePair<string,string>("btnLogin","Go%21")
});
var outputDoc = await client.PostAsync("http://xxx/default.aspx", formContent1);
html = await outputDoc.Content.ReadAsStringAsync();
doc.LoadHtml(html);
// parsing(doc);
var studentInfoNode = doc.GetElementbyId("divStudInfo");
var _studentinfonode1 = studentInfoNode.ChildNodes;
var studentInfo = studentInfoNode.ChildNodes[0].ChildNodes;
the above studentInfo object contain required data
I tried using HttpClient + HttpPost but I am ending up in null exception :(
If some ever worked on similar application can you please help me.
Thanks
How do I set the CORS headers for M3U8 file streaming in Chromecast? In my sender (Android) I am setting the Metadata and MediaInfo like this:
metaData = new MediaMetadata(MediaMetadata.MEDIA_TYPE_MOVIE);
metaData.putString(MediaMetadata.KEY_TITLE, "Demo Video");
MediaInfo mediaInfo = new MediaInfo.Builder(
"http://playertest.longtailvideo.com/adaptive/bbbfull/bbbfull.m3u8")
.setContentType("application/vnd.apple.mpegurl")
.setStreamType(MediaInfo.STREAM_TYPE_BUFFERED)
.setMetadata(metaData)
.build();
player.load(client, mediaInfo, true)
.setResultCallback(new ResultCallback<RemoteMediaPlayer.MediaChannelResult>() {
#Override
public void onResult(RemoteMediaPlayer.MediaChannelResult mediaChannelResult) {
Status status = mediaChannelResult.getStatus();
if (status.isSuccess()) {
}
}
});
My onLoad method is set up like this:
mediaManager.onLoad = function(event) {
console.log("### Media Manager - LOAD: " + JSON.stringify(event));
if(mediaPlayer !== null) {
mediaPlayer.unload(); // Ensure unload before loading again
}
if (event.data['media'] && event.data['media']['contentId']) {
var url = event.data['media']['contentId'];
mediaHost = new cast.player.api.Host({
'mediaElement': mediaElement,
'url': url
});
mediaHost.onError = function (errorCode) {
console.error('### HOST ERROR - Fatal Error: code = ' + errorCode);
if (mediaPlayer !== null) {
mediaPlayer.unload();
}
}
var initialTimeIndexSeconds = event.data['media']['currentTime'] || 0;
// TODO: real code would know what content it was going to access and this would not be here.
var protocol = null;
var parser = document.createElement('a');
parser.href = url;
var ext = ext = parser.pathname.split('.').pop();
if (ext === 'm3u8') {
protocol = cast.player.api.CreateHlsStreamingProtocol(mediaHost);
} else if (ext === 'mpd') {
protocol = cast.player.api.CreateDashStreamingProtocol(mediaHost);
} else if (ext === 'ism/') {
protocol = cast.player.api.CreateSmoothStreamingProtocol(mediaHost);
}
console.log('### Media Protocol Identified as ' + ext);
if (protocol === null) {
mediaManager['onLoadOrig'](event); // Call on the original callback
} else {
mediaPlayer = new cast.player.api.Player(mediaHost);
mediaPlayer.load(protocol, initialTimeIndexSeconds);
}
}
}
However, I am getting this error:
XMLHttpRequest cannot load http://playertest.longtailvideo.com/adaptive/bbbfull/bbbfull.m3u8. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin '----' is therefore not allowed access.
For Chromecast, how do I set the CORS headers for Chromecast?
Probably too late, but just came across with the same issue and get it done by the approach mentioned below.
I didn't get a way to add headers on sender app side so, sharing my own experience. I get the CORS issue fixed upon firstly confirming that my server is supporting CORS. And then for playing the media on chromecast, i was needed to add gstatic.com and in my case another one as well as allowed domains on server, which is in-fact the whole idea of CORS, that each domain should be known to our server. And that's it.
Note: Be very much sure to go through this official documentation. But for being a beginner it may appear a bit tricky to grab all the stuff from here. So shared own experience as well.
How to display JSON coming from php in intel App Framwork app. I have tried .getJSON() and .getJSONP() methods. Is there any full guide explaining these methods and how to use them?
Here are documentations for $.getJSON() and $.jsonP()
found the answer .
function getRaceData() {
var postBody = "";
postBody = "rid="+theRID;
var parameters = new AppMobi.Device.RemoteDataParameters();
parameters.url = "http://MyWebSite.com/php_src/getRaceData.php";
parameters.id = "1007";
parameters.method = "POST";
parameters.body = postBody;
jq.ui.showMask('loading race data');
AppMobi.device.getRemoteDataExt(parameters);
}
//then somewhere in your event handler, check the ID of the response and process the JSON....
case 1007: //got race data
var raceData = jq.parseJSON(event.response);
jq("#raceRCList").hide();
jq("#raceRCname").html(raceData.race_name);
jq("#raceRCdate").val(raceData.date);
jq("#raceRCstart").val(raceData.start_time);
jq("#raceRCData").show();
break;