-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
New process to upload a broadcast replay to IGTV #1364
base: master
Are you sure you want to change the base?
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
/* tslint:disable:no-console */ | ||
import {IgApiClient, LiveEntity} from '../src'; | ||
import Bluebird = require('bluebird'); | ||
const pngToJpeg = require('png-to-jpeg') | ||
const sharp = require('sharp'); | ||
const https = require('https'); | ||
|
||
const ig = new IgApiClient(); | ||
|
||
async function login() { | ||
ig.state.generateDevice(process.env.IG_USERNAME); | ||
ig.state.proxyUrl = process.env.IG_PROXY; | ||
await ig.account.login(process.env.IG_USERNAME, process.env.IG_PASSWORD); | ||
} | ||
|
||
(async () => { | ||
// basic login-procedure | ||
await login(); | ||
|
||
const {broadcast_id, upload_url} = await ig.live.create({ | ||
// create a stream in 720x1280 (9:16) | ||
previewWidth: 720, | ||
previewHeight: 1280, | ||
// this message is not necessary, because it doesn't show up in the notification | ||
message: 'My message', | ||
}); | ||
// (optional) get the key and url for programs such as OBS | ||
const {stream_key, stream_url} = LiveEntity.getUrlAndKey({broadcast_id, upload_url}); | ||
console.log(`Start your stream on ${stream_url}.\n | ||
Your key is: ${stream_key}`); | ||
|
||
/** | ||
* make sure you are streaming to the url | ||
* the next step will send a notification / start your stream for everyone to see | ||
*/ | ||
const startInfo = await ig.live.start(broadcast_id); | ||
// status should be 'ok' | ||
console.log(startInfo); | ||
|
||
/** | ||
* now, your stream is running | ||
* the next step is to get comments | ||
* note: comments can only be requested roughly every 2s | ||
*/ | ||
|
||
// initial comment-timestamp = 0, get all comments | ||
let lastCommentTs = await printComments(broadcast_id, 0); | ||
|
||
// enable the comments | ||
await ig.live.unmuteComment(broadcast_id); | ||
/** | ||
* wait 2 seconds until the next request. | ||
* in the real world you'd use something like setInterval() instead of Bluebird.delay() / just to simulate a delay | ||
*/ | ||
// wait 2s | ||
await Bluebird.delay(2000); | ||
// now, we print the next comments | ||
lastCommentTs = await printComments(broadcast_id, lastCommentTs); | ||
|
||
// now we're commenting on our stream | ||
await ig.live.comment(broadcast_id, 'A comment'); | ||
|
||
/** | ||
* now, your stream is running, you entertain your followers, but you're tired and | ||
* we're going to stop the stream | ||
*/ | ||
await ig.live.endBroadcast(broadcast_id); | ||
|
||
// Get live thumbnails, required to post on IGTV | ||
let data = await ig.live.getPostLiveThumbnails(broadcast_id) | ||
|
||
// Download any thumb | ||
let file = await new Promise((resolve) => https.get(data.thumbnails[0], (download) => { | ||
let ds = []; | ||
download.on("data", (d) => ds.push(d)); | ||
download.on("end", () => resolve(Buffer.concat(ds))) | ||
})) | ||
|
||
// (optional) Resize thumb to a vertical one | ||
file = await sharp(file) | ||
.resize(720, 1280) | ||
.png() | ||
.toBuffer() | ||
|
||
// It will be a png, it must be converted to jpg | ||
file = await pngToJpeg({quality: 100})(file) | ||
|
||
// Upload the thumbnail with a broadcast id for a replay and get uploadId | ||
let upload = await ig.upload.photo({file, broadcastId: broadcast_id}) | ||
|
||
let igtv = null | ||
let currentRetry = 0 | ||
let maxRetry = 3 | ||
let retryDelay = 4 | ||
while (!igtv) { | ||
// This endpoint can return an error "202 Accepted; Transcode not finished yet" if Instagram has not finished to process the previous upload, so retry later in this case | ||
try { | ||
igtv = await ig.media.configureToIgtv({ | ||
upload_id: upload.upload_id, | ||
title: 'A title', | ||
caption: 'A description', | ||
igtv_share_preview_to_feed: '1', | ||
}) | ||
|
||
console.log(`Live posted to IGTV : ${igtv.upload_id}`)) | ||
} catch (e) { | ||
currentRetry++ | ||
if (currentRetry > maxRetry) { | ||
throw e | ||
} else { | ||
await (new Promise(resolve => { | ||
setTimeout(resolve, currentRetry * retryDelay) | ||
})) | ||
} | ||
} | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This could live in its own function and not pollute the current function. For example: async function retryDelayed<T>(fn: () => Promise<T>, retryOptions: { retries: number, delayMs: number }): Promise<T> {
let step = 0;
while(step++ < retryOptions.retries) {
try {
return await fn();
} catch(e) {
if(step >= retryOptions.retries) throw e;
await new Promise(r => setTimeout(r, step * retryOptions.delayMs));
}
}
}
// used like this:
const user = await retryDelayed(() => ig.user.info(123), {retries: 2, delayMs: 2 * 1000 /* 2s */ }); There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for the tips @Nerixyz . There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. content/site-policy/content-removal-policies/github-private-information-removal-policy.md There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
||
// now you're basically done | ||
})(); | ||
|
||
async function printComments(broadcastId, lastCommentTs) { | ||
const {comments} = await ig.live.getComment({broadcastId, lastCommentTs}); | ||
if (comments.length > 0) { | ||
comments.forEach(comment => console.log(`${comment.user.username}: ${comment.text}`)); | ||
return comments[comments.length - 1].created_at; | ||
} else { | ||
return lastCommentTs; | ||
} | ||
} |
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here you could use
request-promise
as it's already a dependency of this library.