YouTube Live Streaming API in swift - ios

I'm so sorry for asking such a basic question.
I've been struggling for a few days.
Because Google api documents are really the worst.
Here's how I am now.
With GoogleSignIn, OAuth is done. (It has information such as user ID, token, and API key...)
Success fetch playlist
func fetchPlaylist(id: String) {
let url = self.baseURL + "/playlists"
let params = ["part": "snippet", "id": id, "key": self.apiKey]
Alamofire.request(url, method: .get, parameters: params, encoding: URLEncoding.default, headers: nil).responseJSON { (response) in
if let response = response.result.value {
print(response)
} else {
print("error")
}
}
}
//////////// 👇result👇
{
etag = "\"XI7nbFXulYBIpL0ayR_gDh3eu1k/ewwRz0VbTYpp2EGbOkvZ5M_1mbo\"";
items = (
);
kind = "youtube#playlistListResponse";
pageInfo = {
resultsPerPage = 5;
totalResults = 0;
};
}
How to start Live Broadcast??
I think it's a stupid question.
But I'm really desperate.
https://developers.google.com/youtube/v3/live/docs/liveBroadcasts/insert
According to this document, must specify a value for these properties.
snippet.title
snippet.scheduledStartTime
status.privacyStatus
And also required parameters is part.
"The part parameter serves two purposes in this operation. It identifies the properties that the write operation will set as well as the properties that the API response will include.
The part properties that you can include in the parameter value are id, snippet, contentDetails, and status."
But what the hell is this? cotentDetails?? status?? snippet??
I couldn't find this information anywhere in the document.
I don't know what to do.
Please help me.

Based from this documentation:
contentDetails
The contentDetails object contains information about the video content, including the length of the video and an indication of whether captions are available for the video.
status
The status object contains information about the video's uploading, processing, and privacy statuses.
snippet
The snippet object contains basic details about the video, such as its title, description, and category.
You need to provide a liveBroadcast resource in the request body. You may also check this link as an example.
YTLiveStreaming
YTLiveStreaming is a framework for creating live broadcasts and video streams on YouTube using the YouTube Live Streaming API (YouTube Data API v3) in Swift 4

Related

How to get link to third party site in 'about channel' section via python

I want to display information about links in the YouTube profile in a text document, I tried to do it through the requests library, but Google gave links to privacy and security, I did not find information about this in the YouTube API documentation. Who knows, you can help with this
This isn't possible to get using the YouTube API, I actually found myself needing to do the same thing as yourself and was not able to because the YouTube API lacked the necessary functionality (Hopefully, It will be added soon!)
I see you mentioned Python, My only solution is in Node but I will do a large explanation and you can base your code off of it. In order to get the banner links without the YouTube API, we need to scrape the data, since YouTube uses client-side rendering we need to scrape the JSON configuration from the source.
There's a variable defined inside a script called ytInitialData which is a big JSON string with a massive amount of information about the channel, viewer, and YouTube configurations. We can find the banner links by parsing through this JSON link.
const request = require("request-promise").defaults({
simple: false,
resolveWithFullResponse: true
})
const getBannerLinks = async () => {
return request("https://www.youtube.com/user/pewdiepie").then(res => {
if (res.statusCode === 200) {
const parsed = res.body.split("var ytInitialData = ")[1].split(";</script>")[0]
const data = JSON.parse(parsed)
const links = data.header.c4TabbedHeaderRenderer.headerLinks.channelHeaderLinksRenderer
const allLinks = links.primaryLinks.concat(links.secondaryLinks || [])
const parsedLinks = allLinks.map(l => {
const url = new URLSearchParams(l.navigationEndpoint.commandMetadata.webCommandMetadata.url)
return {
link: url.get("q"),
name: l.title.simpleText,
icon: l.icon.thumbnails[0].url
}
})
return parsedLinks
} else {
// Error/ratelimit - Handle here
}
})
}
The way the links are scraped is as follows:
We make a HTTP request to the channel's URL
We parse the body to extract the JSON string that the banner links are inside using split
We parse the JSON string into a JSON object
We extract the links from their JSON section (It's a big JSON object data.header.c4TabbedHeaderRenderer.headerLinks.channelHeaderLinksRenderer
Because there are two types of links (Primary, the one that shows the text and secondary, links that don't show the text) we have to concatenate them together so we can map through them
We then map through the links and use URLSearchParams to extract the q query parameter since YouTube encrypts their outgoing links (Most likely for security reasons) and then extract the name and icon too using their appropriate objects.
This isn't a perfect solution, should YouTube update/change anything on their front end this could break your program easily. YouTube also has rate limits for their software if you're trying to mass scrape you'll run into 429/403 errors.

Does a iOS post request has to look same as what rest api expects?

I have to send a JSON file that I collect on my iOS to my backend team. The JSON looks something like:
{
"samples" : [
{
"acw" : 11,
"e_reserved" : 0,
"acc" : 28,
"cheat_rate" : 16,
}
]
}
I am making a post request to backend at:
http://make-post.com/api/post-activities
The backend expects the JSON as:
/api/post-activities/
Request Body
The request body should be a "application/json" encoded object,
containing the following items.
Parameter Description
name
time_stamp
duration
We do not collect all these data ourselves but backend has to process the data we supply and get those info.
What I tried first was to put all these data in an online storage and create a request as:
Request: {“pod_id”:“F11”,“type”:“Normal Activity”,“time_stamp”:“2019-04-17T22:29:35.147Z”,“url”:“https:\/\/s3.amazonaws.com\/mybucket-test\/myid#gmail.com\/2019-04-17\/d9335.json”}
But when I send request like this, I get Status Code 400 error.
So my next idea was to pass the whole JSON I collect to them. Upon doing that, they can get the data and see it in there database even though I get 500 error. Does it mean it is not really working?
The question is unclear to me, The learnings I have learnt you have some data that you want to pass to backend, and the backend sends 400 as you are not meeting his desire.
Suppose you have three variables to pass , let name,time_stamp, duration.
All you need to do in Swift, use Codable protocol.
class postJSON : Codable {
var name : String?
var time_stamp : String? // it may be Int64 according to backend what accept
var duration : String? // it may be Int64 according to backend what accept
}
While making a post request just do
let encodedData = try? JSONEncoder().encode(postJSON)

YouTube API V3 - Get recommended video for new feed

As YouTube official documentation about implement and immigrate to API V3, they said:
YouTube Data API (v2) functionality: Retrieve video recommendations
The v3 API does not retrieve a list that only contains videos recommended for the current API user. However, you can use the v3 API to find recommended videos by calling the activities.list method and setting the home parameter value to true.
But now the parameter home has been deprecated too.
Currently, when I set the home parameter to true, I only retrieve the recently uploaded video in the channel: Popular video in YouTube. There are no video with snippet.type=recommendation at all.
I need to show recommended videos of authenticated user in new feed, but seem like this feature is completely deprecated by YouTube.
Anyone has solution for that?
Thanks first!
Unfortunately, I can't find any documentation or example about this feature. It seems that this has been deprecated. However, you may check this documentation with sample JSON structure that shows the format of a activities resource such as recommendation:
"recommendation": {
"resourceId": {
"kind": string,
"videoId": string,
"channelId": string,
},
Hope this helps!
I found this youtubes search api. All we need to do is put a video id in the relatedToVideoId and it'll giveout a list of videos related to it.
The docs for the api include a way to test the request. code samples there show how to set 'mine' for an authenticated request.
youtube activities
This is android sample code. it would need to be in some background thread. The setmine = true on the channelList response is like the home (I think). Was not sure if your implementation was for the web or an app.
this is android code:
YouTube youtube = new YouTube.Builder(transport, jsonFactory,
credential).setApplicationName(getString(R.string.app_name))
.build();
YouTube.Activities.List activities;
ActivityListResponse activityListResponse = null;
List<ActivityData> activitiesData = new ArrayList<ActivityData>();
try {
/*
* Now that the user is authenticated, the app makes a
* channels list request to get the authenticated user's
* channel. Returned with that data is the playlist id for
* the uploaded videos.
* https://developers.google.com/youtube
* /v3/docs/channels/list
*/
ChannelListResponse clr = youtube.channels().list("contentDetails")
.setMine(true).execute();
activities = youtube.activities().list("id,snippet,subscriberSnippet");
activities.setChannelId(clr.getItems().get(0).getId());
activities.setMaxResults((long) 50);
activityListResponse = activities.execute();
ArrayList<String> subscriptionListIdentifier = new ArrayList<String>()
,listTitles = new ArrayList<String>()
,listThumbnails = new ArrayList<String>();
List<Activity> results = activityListResponse.getItems();
for (Activity activity : results) {
listTitles.add(activity.getSnippet().getTitle());
listThumbnails.add(activity.getSnippet().getThumbnails().getDefault().getUrl());
subscriptionListIdentifier.add(activity.getId());
//if ("public".equals(playlist.getStatus()
// .getPrivacyStatus())) {
ActivityData data = new ActivityData();
data.setActivity(activity);
activitiesData.add(data);
//}
}
return activitiesData;
You can retrieve them using the following API call:
GET https://www.googleapis.com/youtube/v3/activitiespart=snippet%2CcontentDetails&channelId={channel—_Id}&maxResults=25&regionCode=tw&key={YOUR_API_KEY}

How to retrieve Medium stories for a user from the API?

I'm trying to integrate Medium blogging into an app by showing some cards with posts images and links to the original Medium publication.
From Medium API docs I can see how to retrieve publications and create posts, but it doesn't mention retrieving posts. Is retrieving posts/stories for a user currently possible using the Medium's API?
The API is write-only and is not intended to retrieve posts (Medium staff told me)
You can simply use the RSS feed as such:
https://medium.com/feed/#your_profile
You can simply get the RSS feed via GET, then if you need it in JSON format just use a NPM module like rss-to-json and you're good to go.
Edit:
It is possible to make a request to the following URL and you will get the response. Unfortunately, the response is in RSS format which would require some parsing to JSON if needed.
https://medium.com/feed/#yourhandle
⚠️ The following approach is not applicable anymore as it is behind Cloudflare's DDoS protection.
If you planning to get it from the Client-side using JavaScript or jQuery or Angular, etc. then you need to build an API gateway or web service that serves your feed. In the case of PHP, RoR, or any server-side that should not be the case.
You can get it directly in JSON format as given beneath:
https://medium.com/#yourhandle/latest?format=json
In my case, I made a simple web service in the express app and host it over Heroku. React App hits the API exposed over Heroku and gets the data.
const MEDIUM_URL = "https://medium.com/#yourhandle/latest?format=json";
router.get("/posts", (req, res, next) => {
request.get(MEDIUM_URL, (err, apiRes, body) => {
if (!err && apiRes.statusCode === 200) {
let i = body.indexOf("{");
const data = body.substr(i);
res.send(data);
} else {
res.sendStatus(500).json(err);
}
});
});
Nowadays this URL:
https://medium.com/#username/latest?format=json
sits behind Cloudflare's DDoS protection service so instead of consistently being served your feed in JSON format, you will usually receive instead an HTML which is suppose to render a website to complete a reCAPTCHA and leaving you with no data from an API request.
And the following:
https://medium.com/feed/#username
has a limit of the latest 10 posts.
I'd suggest this free Cloudflare Worker that I made for this purpose. It works as a facade so you don't have to worry about neither how the posts are obtained from source, reCAPTCHAs or pagination.
Full article about it.
Live example. To fetch the following items add the query param ?next= with the value of the JSON field next which the API provides.
const MdFetch = async (name) => {
const res = await fetch(
`https://api.rss2json.com/v1/api.json?rss_url=https://medium.com/feed/${name}`
);
return await res.json();
};
const data = await MdFetch('#chawki726');
To get your posts as JSON objects
you can replace your user name instead of #USERNAME.
https://api.rss2json.com/v1/api.json?rss_url=https://medium.com/feed/#USERNAME
With that REST method you would do this: GET https://api.medium.com/v1/users/{{userId}}/publications and this would return the title, image, and the item's URL.
Further details: https://github.com/Medium/medium-api-docs#32-publications .
You can also add "?format=json" to the end of any URL on Medium and get useful data back.
Use this url, this url will give json format of posts
Replace studytact with your feed name
https://api.rss2json.com/v1/api.json?rss_url=https://medium.com/feed/studytact
I have built a basic function using AWS Lambda and AWS API Gateway if anyone is interested. A detailed explanation is found on this blog post here and the repository for the the Lambda function built with Node.js is found here on Github. Hopefully someone here finds it useful.
(Updating the JS Fiddle and the Clay function that explains it as we updated the function syntax to be cleaner)
I wrapped the Github package #mark-fasel was mentioning below into a Clay microservice that enables you to do exactly this:
Simplified Return Format: https://www.clay.run/services/nicoslepicos/medium-get-user-posts-new/code
I put together a little fiddle, since a user was asking how to use the endpoint in HTML to get the titles for their last 3 posts:
https://jsfiddle.net/h405m3ma/3/
You can call the API as:
curl -i -H "Content-Type: application/json" -X POST -d '{"username":"nicolaerusan"}' https://clay.run/services/nicoslepicos/medium-get-users-posts-simple
You can also use it easily in your node code using the clay-client npm package and just write:
Clay.run('nicoslepicos/medium-get-user-posts-new', {"profile":"profileValue"})
.then((result) => {
// Do what you want with returned result
console.log(result);
})
.catch((error) => {
console.log(error);
});
Hope that's helpful!
Check this One you will get all info about your own post........
mediumController.getBlogs = (req, res) => {
parser('https://medium.com/feed/#profileName', function (err, rss) {
if (err) {
console.log(err);
}
var stories = [];
for (var i = rss.length - 1; i >= 0; i--) {
var new_story = {};
new_story.title = rss[i].title;
new_story.description = rss[i].description;
new_story.date = rss[i].date;
new_story.link = rss[i].link;
new_story.author = rss[i].author;
new_story.comments = rss[i].comments;
stories.push(new_story);
}
console.log('stories:');
console.dir(stories);
res.json(200, {
Data: stories
})
});
}
I have created a custom REST API to retrieve the stats of a given post on Medium, all you need is to send a GET request to my custom API and you will retrieve the stats as a Json abject as follows:
Request :
curl https://endpoint/api/stats?story_url=THE_URL_OF_THE_MEDIUM_STORY
Response:
{
"claps": 78,
"comments": 1
}
The API responds within a reasonable response time (< 2 sec), you can find more about it in the following Medium article.

Facebook Graph API object_id missing sometimes

I am using the Facebook Graph API to get the news feed of a user.
My request URL is:
xxxxxxxxxxxxxx/feed?fields=from,id,created_time,picture,link,object_id,message, likes.fields(id)
With the object_id, I want to get the big picture of the post, using the following url:
http://graph.facebook.com/OBJECT_ID/picture?type=normal
The picture return field is always filled, but the object_id is not being returned at some posts. Why is this? I really need the high res picture, and didn't find another way to acquire this..
The object_id is only returned if the attachment is a facebook object (e.g. an image uploaded by the user). Some stories in feed don't have a picture at all, and some pictures are not facebook objects (e.g. thumbnails for shared links).
Sometimes Facebook keeps a thumbnail of an image and stores an external link to the larger version of the image in the URL returned by the graph request. In order to access the images in either case, I used the code below, where smallURL is the URL returned by the graph request:
private String getRealURL(String smallURL){
if (smallURL.contains("url=http")){
String[] pieces = smallURL.split("url=");
pieces[1].replace("%2F", "//");
pieces[1].replace("%3A", ":");
return pieces[1];
}
else{
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.setLength(0);
stringBuilder.append("http://graph.facebook.com/");
stringBuilder.append(item.getObjectID());
stringBuilder.append("/picture?type=large");
return stringBuilder.toString();
}
}
I also noticed that some FB posts didn't have {object_id} for large photos, but realized that the {picture} thumbnail URL contains the encoded URL of the original larger image:
https://external.xx.fbcdn.net/safe_image.php?d=AQBe9UvGd0vPbAHP&w=130&h=130&url=http%3A%2F%2Fskift.com%2Fwp-content%2Fuploads%2F2015%2F12%2Fpollution.jpg&cfs=1
--> contains -->
http://skift.com/wp-content/uploads/2015/12/pollution.jpg
So I check for {object_id}, and if not then try to extract the original URL from {picture}:
if(isset($post['object_id'])) {
echo "http://graph.facebook.com/".$post['object_id']."/picture";
}
elseif(isset($post['picture'])) {
echo urldecode(preg_replace('/&cfs.*/', '', preg_replace('/.*url=/', '', $post['picture'])));
}
else {
echo "no_large_image";
}

Resources