I am using exoplayer 2.7.3 and when i am trying to play some url i get below error:
E/ExoPlayerImplInternal: Source error.
com.google.android.exoplayer2.upstream.HttpDataSource$InvalidResponseCodeException: Response code: 401
I can able to play same url in some other place in app. But at this place this issue happens.
Can anyone help me what might be wrong?
First, try to play the streaming on some web browser, if it fails, the problem is with this link.
The error 401 means that you not have permission to access this content.
Because you haven't set token for your data source. Set token like this :
// Create a data source factory.
val headersMap: MutableMap<String, String> = HashMap()
headersMap["Authorization"] = "Bearer ${"your token"}"
val dataSourceFactory: DataSource.Factory =
DefaultHttpDataSource.Factory().setDefaultRequestProperties(headersMap)
Related
I'm trying to stream content from a URL that returns a 404 if you're not logged in or a 302 redirect if you are. To log in, I need to pass a cookie in the headers for Exoplayer's requests, but I'm struggling to work out how.
Previous answers suggest using a default Cookie Manager instance with your cookies already set. Others suggest setting the header as a map in HttpDataFactory.setDefaultRequestProperty. Neither has worked for me.
Here's my work so far.
val cookieManager = CookieManager()
cookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ORIGINAL_SERVER)
val cookie = HttpCookie("identity", state.token)
cookieManager.cookieStore.add(URI("<URL>"), cookie)
if (CookieHandler.getDefault() != cookieManager) {
CookieHandler.setDefault(cookieManager)
}
val player = ExoPlayer.Builder(context)
.setAudioAttributes(AudioAttributes.DEFAULT, true)
.setMediaSourceFactory(
DefaultMediaSourceFactory(context)
).build()
val session = MediaSession.Builder(context, player).build()
session.player.addMediaItem(MediaItem.fromUri(state.currentTrack.file.values.first()))
session.player.prepare()
session.player.play()
Hardcoding the URL to the redirected URL streams just fine, so I know it's an issue of just passing the relevant cookie. Help would be appreciated!
val sendlink=URL(
"$graphlink?grant_type=ig_exchange_token&client_secret=$Clientid&access_token=$shortlived")
return sendlink.readText()
ı want to make a Get Request and this is the easiest way( I have tried the as HttpUrlConnection it gives same error )
But this code give error like here :
java.io.FileNotFoundException: https://graph.instagram.com/access_token?grant_type=ig_exchange_token&client_secret={mysecret}&access_token={Token}
This kind of library gives FileNotFoundException Error for the request code 401 or higher.
I'm trying to play Vimeo video using ExoPlayer and here is the code:
val dataSourceFactory = DefaultDataSourceFactory(requireContext(),
getUserAgent(requireContext(), requireContext().getString(R.string.app_name)))
val videoSource = ProgressiveMediaSource.Factory(dataSourceFactory)
.createMediaSource(Uri.parse(videoLink))
player.prepare(videoSource)
This throw the following exception:
com.google.android.exoplayer2.upstream.HttpDataSource$InvalidResponseCodeException: Response code: 403
at com.google.android.exoplayer2.upstream.DefaultHttpDataSource.open(DefaultHttpDataSource.java:300)
at com.google.android.exoplayer2.upstream.DefaultDataSource.open(DefaultDataSource.java:177)
at com.google.android.exoplayer2.upstream.StatsDataSource.open(StatsDataSource.java:83)
at com.google.android.exoplayer2.source.ProgressiveMediaPeriod$ExtractingLoadable.load(ProgressiveMediaPeriod.java:961)
at com.google.android.exoplayer2.upstream.Loader$LoadTask.run(Loader.java:391)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
at java.lang.Thread.run(Thread.java:764)
Also I tried to extract the Vimeo url using AndroidVimeoExtractor and it fails with the following exception:
java.io.IOException: Video has restricted playback
Here is the code:
VimeoExtractor.getInstance().fetchVideoWithIdentifier(
"videoIdentifier",
null,
object : OnVimeoExtractionListener {
override fun onSuccess(video: VimeoVideo) {
Logger.i("video: ${video.streams.size}")
}
override fun onFailure(throwable: Throwable) {
Logger.e(throwable)
}
})
And here is a sample of Vimeo video link: http://player.vimeo.com/external/videoIdentifier.sd.mp4?s=value&profile_id=value&oauth2_token_id=value
Note: I'm not the person who uploaded the video. Also, when I put the link in Google Chrome Browser it redirects to another link and plays video normally. So I need something like that to get the final link to pass it to ExoPlayer.
There is 2 ways to handle this issue
First solution
Using Vimeo networking API to get video URI and to use it
create app on vimeo developer
using your app access token and video Id you can get Video Url then pass it to Exo player
Second Solution (it's a work around and fast solution)
using web view to redirect to .mp4 url, then use the redirected url ends with.mp4 to open it with Exo player
webView = WebView(context).apply {
settings.javaScriptEnabled = false
webViewClient = object : WebViewClient() {
override fun shouldOverrideUrlLoading(view: WebView?, request: WebResourceRequest?): Boolean {
val requestUrl = request?.url.toString()
val uri = requestUrl.toUri()
if (isVideoLink(requestUrl)) {
preparePlayer(uri)
webView?.release()
webView = null
return true
}
return false
}
}
loadUrl(url)
}
fun isVideoLink(url: String): Boolean {
return getMimeType(url)?.contains("video", true) ?: false
}
Are you trying to play all Vimeo Videos, or just Vimeo videos you've uploaded?
I think the issue is the mp4 file you're pulling isn't actually valid or you don't have permissions to stream it given your oauth token (if you don't own it).
You can check out the vimeo-networking library README here.
The basic requirements for native playback are:
User must be logged in.
User must be the owner of the video.
User must be PRO or higher (or the app must have the "can access owner's video files" capability).
Token must have the video_files scope.
User must be the owner of the API app making the request.
If you satisfy all of those requirements, then you can make an API request to Vimeo and they'll give you back a valid MP4 file you can pass as the videoLink.
// Obtain a video you own my making a GET request
Video video = ...;
Play play = video.getPlay();
// This will be a list of "progressive" video files (basically just MP4s of different resolutions that you can pass to ExoPlayer
ArrayList<VideoFile> progressiveFiles = play.getProgressiveVideoFiles();
String linkToMp4File = progressiveFiles.get(0).getLink();
val videoSource = ProgressiveMediaSource.Factory(dataSourceFactory)
.createMediaSource(Uri.parse(linkToMp4File))
If you weren't the person who uploaded the video, I think there's a way to get a valid video link, but I've never done it personally. Since all users are allowed to embed any video (if the video is public and embeddable), then you could get the embed link from the API here and then extract the MP4 file link from the embed code maybe? Just an idea.
I am newbie in Titanium and trying to fetch video lists of a particular channel from YouTube using THIS tutorial.
The problem is, all time i get "No videos were found for this search" message(used inside catch exception) and from Chrome console i get the exception message:
"No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin localhost:8020 is therefore not allowed access. Failed to load resource: the server responded with a status of 503 (Service Unavailable)"
Can anyone point me out what solution would be for this problem? From some googling, i see that is not the problem inside the code, it's a server-side problem, so how can i overcome this YouTube response problem?
And i also checked that, this line var doc = this.responseXML.documentElement; always results to null that's what no videos are found. I used instead:
if (!this.responseXML)
{
//if not XML you have to convert it to XML
doc = Titanium.XML.parseString(this.responseText).documentElement;
}
else
{
//if it is XML, then just set the doc variable
doc = this.responseXML.documentElement;
}
Still doc is null alltime! Thanks in advance for any suggestion.
Well, i solved the problem. In fact that was a browser issue, when i tested in desktop, browser uses localhost:8020 as the address and YouTube didn't response back for that address.
Later, i tested it a real android device and voila!, it works..var doc = this.responseXML.documentElementclearly contains the responseXML and then it extract video information by var items = doc.getElementsByTagName("entry").
Hope that could help someone someday!
I'm using the Apache Amber libraries to try to retrieve an OAuth2 access token from a Web site under my control. My client code is running under Android.
My code is patterned on the example at:
https://cwiki.apache.org/confluence/display/AMBER/OAuth+2.0+Client+Quickstart
In the first step, I'm able to retrieve a "code" by submitting a GET request using a WebView browser:
OAuthClientRequest request = OAuthClientRequest
.authorizationLocation(AUTHORIZE_URL)
.setClientId(CLIENT_ID)
.setRedirectURI(REDIR_URL)
.setResponseType(CODE_RESPONSE)
.buildQueryMessage();
webview.loadUrl(request.getLocationUri());
I use a WebViewClient callback to capture the redirect URL with the "code" parameter. So far, so good.
Using that code, I try to retrieve my access token:
OAuthClient oAuthClient = new OAuthClient(new URLConnectionClient());
OAuthClientRequest request = OAuthClientRequest
.tokenLocation(ACCESS_TOKEN_URL)
.setGrantType(GrantType.AUTHORIZATION_CODE)
.setClientId(CLIENT_ID)
.setClientSecret(CLIENT_SECRET)
.setRedirectURI(REDIR_URL)
.setCode(code)
.buildBodyMessage();
GitHubTokenResponse oAuthResponse =
oAuthClient.accessToken(request, GitHubTokenResponse.class);
Each time I run my code, I get an OAuthProblemException, where the message is that I have an invalid request due to a missing parameter, access_token.
Another StackOverflow post mentions this exception from a similar OAuth2 request, which in that case was caused by having different redirect URIs across OAuth requests. But I've made sure my redirect URIs are the same by using a named constant. Here's the link to that post:
OAuthProblem, missing parameter access_token
Now, I can print out the code returned by the first request, and paste it into a curl command run from my desktop machine:
curl -d "code=...&client_id=...&client_secret=...&grant_type=...&redirect_uri=..." http://my_website.com
and I get a nice JSON response from my site with an access_token.
Why does the call from Java fail, where my hand-rolled command line succeeds?
I had the same problem implementing the client and the server, the problem is about one mistake in the Client Example in the Apache Amber (Oltu) project:
First you have the Auth code request (which work):
OAuthClientRequest request = OAuthClientRequest
.authorizationLocation(AUTHORIZE_URL)
.setClientId(CLIENT_ID)
.setRedirectURI(REDIR_URL)
.setResponseType(CODE_RESPONSE)
.**buildQueryMessage**();
And second the request about the Access Token (which don't work):
OAuthClientRequest request = OAuthClientRequest
.tokenLocation(ACCESS_TOKEN_URL)
.setGrantType(GrantType.AUTHORIZATION_CODE)
.setClientId(CLIENT_ID)
.setClientSecret(CLIENT_SECRET)
.setRedirectURI(REDIR_URL)
.setCode(code)
.**buildBodyMessage**();
The mistake is about the buildBodyMessage() in the second request. Change it by buildQueryMessage().
Solved in my case.
Amber/Oltu "Missing parameter access_token" error may mean that GitHubTokenResponse or OAuthJSONAccessTokenResponse are unabled to translate response body for any reason. In my case (with Google+ oAuth2 authentication), the response body, is not parsed properly to the inner parameters map.
For example:
GitHubTokenResponse
parameters = OAuthUtils.decodeForm(body);
Parse a form-urlencoded result body
... and OAuthJSONAccessTokenResponse has the next parse function
parameters = JSONUtils.parseJSON(body);
This JSONUtils.parseJSON is a custom JSON parser that not allow for me JSON response body from GOOGLE+ and throws an JSONError (console not logged),
Each error throwed parsing this parameters, are not console visible, and then always is throwed doomed "Missing parameter: access_token" or another "missing parameter" error.
If you write your Custom OAuthAccessTokenResponse, you can see response body, and write a parser that works with your response.
This is what I encountered and what I did to get it working:
I quickly put together a similar example described in:
https://cwiki.apache.org/confluence/display/OLTU/OAuth+2.0+Client+Quickstart
and:
svn.apache.org/repos/asf/oltu/trunk/oauth-2.0/client/src/test/java/org/apache/oltu/oauth2/client/OAuthClientTest.java
This was my command to execute it:
java -cp .:./org.apache.oltu.oauth2.client-1.0.1-20150221.171248-36.jar OAuthClientTest
I also ended up with the above mentioned error where the access_token was expected. I ended up debugging in intellij and traced an anomaly with the if condition which checks that the string begins with the "{" character.
In doing so, I also added the following jar to my classpath so that I may debug the trace a little deeper.
./java-json.jar
(downloaded from http://www.java2s.com/Code/Jar/j/Downloadjavajsonjar.htm)
During the next debug session, the code actually started working. My mate and I eventually found the root cause was due to the JSON jar not being included.
This is the command which works:
java -cp .:./java-json.jar:./org.apache.oltu.oauth2.client-1.0.1-20150221.171248-36.jar OAuthClientTest
I was having the same problem when trying to get the access token from fitbit OAuth2. buildBodyMessage() and buildQueryMessage() were both giving me missing parameter, access_token.
I believe this is something to do with the apache oauth2 client library. I ended up making simple post requests using spring's RestTemplate and it's working fine.
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
headers.set("Authorization", "Basic " + "MjI5TkRZOjAwNDBhNDBkMjRmZTA0OTJhNTE5NzU5NmQ1N2ZmZGEw");
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
map.add("client_id", FITBIT_CLIENT_ID);
map.add("grant_type", "authorization_code");
map.add("redirect_uri", Constants.RESTFUL_PATH + "/fitbit/fitbitredirect");
map.add("code", code);
HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(map, headers);
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> response = restTemplate.postForEntity(FITBIT_TOKEN_URI, request, String.class);
log.debug("response.body: " + response.getBody());