Skip to content
This repository has been archived by the owner on Aug 15, 2022. It is now read-only.

Use ffmpeg for live #4

Closed
ahmadd110 opened this issue Apr 23, 2020 · 21 comments
Closed

Use ffmpeg for live #4

ahmadd110 opened this issue Apr 23, 2020 · 21 comments
Labels
help wanted Extra attention is needed question Further information is requested

Comments

@ahmadd110
Copy link

ahmadd110 commented Apr 23, 2020

The following code is related to the live stream of the file using ffmpeg via LevPasha/Instagram-API-python.
LevPasha/Instagram-API-python is dead!
Can you look at it and add this feature to your beautiful code?
Thanks a lot
Sincerely

`#!/usr/bin/env python

-- coding: utf-8 --
Use text editor to edit the script and type in valid Instagram username/password
import subprocess

from InstagramAPI import InstagramAPI

USERNAME = ''
PASSWORD = ''
FILE_PATH = ''
PUBLISH_TO_LIVE_FEED = False
SEND_NOTIFICATIONS = False

api = InstagramAPI(USERNAME, PASSWORD, debug=False)
assert api.login()

first you have to create a broadcast - you will receive a broadcast id and an upload url here
assert api.createBroadcast()
broadcast_id = api.LastJson['broadcast_id']
upload_url = api.LastJson['upload_url']

we now start a boradcast - it will now appear in the live-feed of users
assert api.startBroadcast(broadcast_id, sendNotification=SEND_NOTIFICATIONS)

ffmpeg_cmd = "ffmpeg -rtbufsize 256M -re -i '{file}' -acodec libmp3lame -ar 44100 -b:a 128k -pix_fmt yuv420p -profile:v baseline -s 720x1280 -bufsize 6000k -vb 400k -maxrate 1500k -deinterlace -vcodec libx264 -preset veryfast -g 30 -r 30 -f flv '{stream_url}'".format(
file=FILE_PATH,
stream_url=upload_url,
)

print("Hit Ctrl+C to stop broadcast")
try:
subprocess.call(ffmpeg_cmd, shell=True)
except KeyboardInterrupt:
print('Stop Broadcasting')

assert api.stopBroadcast(broadcast_id)

print('Finished Broadcast')

if PUBLISH_TO_LIVE_FEED:
api.addBroadcastToLive(broadcast_id)
print('Added Broadcast to LiveFeed')
`

@harrypython harrypython added the question Further information is requested label Apr 23, 2020
@harrypython
Copy link
Owner

harrypython commented Apr 23, 2020

With some adaptation yes, it's possible, it's not super friendly but will works, try this:

import json
import subprocess

from ItsAGramLive import ItsAGramLive

FILE_PATH = "/path/to/the/file/you/want/to/streaming"

live = ItsAGramLive()

broadcast_id = live.create_broadcast()

ffmpeg_cmd = "ffmpeg -rtbufsize 256M -re -i '{file}' -acodec libmp3lame -ar 44100 -b:a 128k -pix_fmt yuv420p " \
             "-profile:v baseline -s 720x1280 -bufsize 6000k -vb 400k -maxrate 1500k -deinterlace -vcodec libx264 " \
             "-preset veryfast -g 30 -r 30 -f flv '{stream_url}'" \
    .format(file=FILE_PATH, stream_url=live.LastJson['upload_url'])

data = json.dumps({'_uuid': live.uuid,
                   '_uid': live.username_id,
                   'should_send_notifications': int(live.sendNotification),
                   '_csrftoken': live.token})

if live.send_request(endpoint='live/' + str(broadcast_id) + '/start/', post=live.generate_signature(data)):

    print('CTRL+C to quit.')
    try:
        while True:
            subprocess.call(ffmpeg_cmd, shell=True)
    except KeyboardInterrupt:
        pass
    except Exception as error:
        print(error)
        live.end_broadcast(broadcast_id)

and run

python3 whatevername.py -u yourInstagramUsername -p yourPassword

@ahmadd110
Copy link
Author

Thank you very much for your attention to this feature.

When I run "python3 ffmpegmyfile.py -u Username -p Password"
In the first step shows that it has been successfully login.
In the second step shows url and streamkey.
In the third step again, the process is repeated from first step and shows that it has been successfully login and url and streamkey and this process is repeated (from first step).
On the Instagram page, Live start and end quickly, and this has happened several times.
Until it gives the following error in CMD:

Request return 400 error! {'message': 'Please wait a few minutes before you try again.', 'status': 'fail', 'error_type': 'rate_limit_error'} Traceback (most recent call last): File "ffmpegmyfile.py", line 10, in <module> broadcast_id = live.create_broadcast() File "C:\Users\my\AppData\Local\Programs\Python\Python38-32\lib\site-packages\ItsAGramLive\ItsAGramLive.py", line 208, in create_broadcast if self.login(): File "C:\Users\my\AppData\Local\Programs\Python\Python38-32\lib\site-packages\ItsAGramLive\ItsAGramLive.py", line 102, in login if self.LastJson['two_factor_required']: KeyError: 'two_factor_required' Press any key to continue . . .

@harrypython
Copy link
Owner

Are you using the last version?
Are you using 2FA on your Instagram account? If yes, what kind?

@ahmadd110
Copy link
Author

Are you using the last version? Yes
Are you using 2FA on your Instagram account? No

I think it showed this error because it login several times.
when I run again, it was login success, but it was repeated again and again.

@harrypython
Copy link
Owner

Question: do you clone the project here or are you using pip?

I did a small modification, try again with this code:

import json
import subprocess

from ItsAGramLive import ItsAGramLive

FILE_PATH = "/path/to/the/file/you/want/to/streaming"

live = ItsAGramLive()

broadcast_id = live.create_broadcast()

ffmpeg_cmd = "ffmpeg -rtbufsize 256M -re -i '{file}' -acodec libmp3lame -ar 44100 -b:a 128k -pix_fmt yuv420p " \
             "-profile:v baseline -s 720x1280 -bufsize 6000k -vb 400k -maxrate 1500k -deinterlace -vcodec libx264 " \
             "-preset veryfast -g 30 -r 30 -f flv '{stream_url}'" \
    .format(file=FILE_PATH, stream_url=live.LastJson['upload_url'])

data = json.dumps({'_uuid': live.uuid,
                   '_uid': live.username_id,
                   'should_send_notifications': int(live.sendNotification),
                   '_csrftoken': live.token})

if live.send_request(endpoint='live/' + str(broadcast_id) + '/start/', post=live.generate_signature(data)):

    print('CTRL+C to quit.')
    try:
        subprocess.call(ffmpeg_cmd, shell=True)
    except KeyboardInterrupt:
        pass
    except Exception as error:
        print(error)
    
    live.end_broadcast(broadcast_id)

@ahmadd110
Copy link
Author

ahmadd110 commented Apr 24, 2020

Question: do you clone the project here or are you using pip? pip
please look at these
pervious code http://s11.picofile.com/file/8394993726/error.jpg
new code http://bayanbox.ir/view/4737100089376011253/errorq.jpg

@ahmadd110
Copy link
Author

ahmadd110 commented Apr 24, 2020

The code I put below is code for live stream via Instagram with FFmpeg and php (mgp25/Instagram-API)
I don't know if this is helpful or not
But it's a good idea to take a look at it

`<?php

set_time_limit(0);
date_default_timezone_set('UTC');

require DIR.'/../vendor/autoload.php';

/////// CONFIG ///////
$username = '';
$password = '';
$debug = true;
$truncatedDebug = false;
//////////////////////

/////// MEDIA ////////
$videoFilename = '';
//////////////////////

$ig = new \InstagramAPI\Instagram($debug, $truncatedDebug);

try {
$ig->login($username, $password);
} catch (\Exception $e) {
echo 'Something went wrong: '.$e->getMessage()."\n";
exit(0);
}

try {
// NOTE: This code will create a broadcast, which will give us an RTMP url
// where we are supposed to stream-upload the media we want to broadcast.
//
// The following code is using FFMPEG to broadcast, although other
// alternatives are valid too, like OBS (Open Broadcaster Software,
// https://obsproject.com).
//
// For more information on FFMPEG, see:
// mgp25/Instagram-API#1488 (comment)
// and for OBS, see:
// mgp25/Instagram-API#1488 (comment)

// Get FFmpeg handler and ensure that the application exists on this system.
// NOTE: You can supply custom path to the ffmpeg binary, or just leave NULL
// to autodetect it.
$ffmpegPath = null;
$ffmpeg = \InstagramAPI\Media\Video\FFmpeg::factory($ffmpegPath);

// Tell Instagram that we want to perform a livestream.
$stream = $ig->live->create();
$broadcastId = $stream->getBroadcastId();
$ig->live->start($broadcastId);

$streamUploadUrl = $stream->getUploadUrl();

// Broadcast the entire video file.
// NOTE: The video is broadcasted asynchronously (in the background).
$broadcastProcess = $ffmpeg->runAsync(sprintf(
    '-rtbufsize 256M -re -i %s -acodec libmp3lame -ar 44100 -b:a 128k -pix_fmt yuv420p -profile:v baseline -s 720x1280 -bufsize 6000k -vb 400k -maxrate 1500k -deinterlace -vcodec libx264 -preset veryfast -g 30 -r 30 -f flv %s',
    \Winbox\Args::escape($videoFilename),
    \Winbox\Args::escape($streamUploadUrl)
));

// The following loop performs important requests to obtain information
// about the broadcast while it is ongoing.
// NOTE: This is REQUIRED if you want the comments and likes to appear
// in your saved post-live feed.
// NOTE: These requests are sent *while* the video is being broadcasted.
$lastCommentTs = 0;
$lastLikeTs = 0;
do {
    // Get broadcast comments.
    // - The latest comment timestamp will be required for the next
    //   getComments() request.
    // - There are two types of comments: System comments and user comments.
    //   We compare both and keep the newest (most recent) timestamp.
    $commentsResponse = $ig->live->getComments($broadcastId, $lastCommentTs);
    $systemComments = $commentsResponse->getSystemComments();
    $comments = $commentsResponse->getComments();
    if (!empty($systemComments)) {
        $lastCommentTs = $systemComments[0]->getCreatedAt();
    }
    if (!empty($comments) && $comments[0]->getCreatedAt() > $lastCommentTs) {
        $lastCommentTs = $comments[0]->getCreatedAt();
    }

    // Get broadcast heartbeat and viewer count.
    $heartbeatResponse = $ig->live->getHeartbeatAndViewerCount($broadcastId);

    // Check to see if the livestream has been flagged for a policy violation.
    if ($heartbeatResponse->isIsPolicyViolation() && (int) $heartbeatResponse->getIsPolicyViolation() === 1) {
        echo 'Instagram has flagged your content as a policy violation with the following reason: '.($heartbeatResponse->getPolicyViolationReason() == null ? 'Unknown' : $heartbeatResponse->getPolicyViolationReason())."\n";
        // Change this to false if disagree with the policy violation and would would like to continue streaming.
        // - Note: In this example, the violation is always accepted.
        //   In your use case, you may want to prompt the user if
        //   they would like to accept or refute the policy violation.
        if (true) {
            // Get the final viewer list of the broadcast.
            $ig->live->getFinalViewerList($broadcastId);
            // End the broadcast stream while acknowledging the copyright warning given.
            $ig->live->end($broadcastId, true);
            exit(0);
        }
        // Acknowledges the copyright warning and allows you to continue streaming.
        // - Note: This may allow the copyright holder to view your livestream
        //   regardless of your account privacy or if you archive it.
        $ig->live->resumeBroadcastAfterContentMatch($broadcastId);
    }

    // Get broadcast like count.
    // - The latest like timestamp will be required for the next
    //   getLikeCount() request.
    $likeCountResponse = $ig->live->getLikeCount($broadcastId, $lastLikeTs);
    $lastLikeTs = $likeCountResponse->getLikeTs();

    // Get the join request counts.
    // - This doesn't add support for live-with-friends. Rather,
    //   this is only here to emulate the app's livestream flow.
    $ig->live->getJoinRequestCounts($broadcastId);

    sleep(2);
} while ($broadcastProcess->isRunning());

// Get the final viewer list of the broadcast.
// NOTE: You should only use this after the broadcast has stopped uploading.
$ig->live->getFinalViewerList($broadcastId);

// End the broadcast stream.
// NOTE: Instagram will ALSO end the stream if your broadcasting software
// itself sends a RTMP signal to end the stream. FFmpeg doesn't do that
// (without patching), but OBS sends such a packet. So be aware of that.
$ig->live->end($broadcastId);

// Once the broadcast has ended, you can optionally add the finished
// broadcast to your post-live feed (saved replay).
$ig->live->addToPostLive($broadcastId);

} catch (\Exception $e) {
echo 'Something went wrong: '.$e->getMessage()."\n";
}`

@harrypython
Copy link
Owner

I think it showed this error because it login several times.

There is no reason to login several times, the code it's working fine for me.
Please send me the script ffmpegmyfile.py and the output of this commands:

  1. pip -V
  2. ffmpeg -version
  3. pip -V ItsAGramLive

@ahmadd110
Copy link
Author

import json
import subprocess

from ItsAGramLive import ItsAGramLive

FILE_PATH = "1.mp4"

live = ItsAGramLive()

broadcast_id = live.create_broadcast()

ffmpeg_cmd = "ffmpeg -rtbufsize 256M -re -i '{file}' -vf 'transpose=1' -acodec libmp3lame -ar 44100 -b:a 128k -pix_fmt yuv420p "
"-profile:v baseline -s 720x1280 -bufsize 6000k -vb 400k -maxrate 1500k -deinterlace -vcodec libx264 "
"-preset veryfast -g 30 -r 30 -f flv '{stream_url}'"
.format(file=FILE_PATH, stream_url=live.LastJson['upload_url'])

data = json.dumps({'_uuid': live.uuid,
'_uid': live.username_id,
'should_send_notifications': int(live.sendNotification),
'_csrftoken': live.token})

if live.send_request(endpoint='live/' + str(broadcast_id) + '/start/', post=live.generate_signature(data)):

print('CTRL+C to quit.')
try:
    subprocess.call(ffmpeg_cmd, shell=True)
except KeyboardInterrupt:
    pass
except Exception as error:
    print(error)

live.end_broadcast(broadcast_id)

@ahmadd110
Copy link
Author

c:>pip -V
pip 20.0.2 from c:\users\my\appdata\local\programs\python\python38-32\lib\site-packages\pip (python 3.8)
..........................................................................
c:>ffmpeg -version
ffmpeg version git-2020-04-24-a501947 Copyright (c) 2000-2020 the FFmpeg developers
built with gcc 9.3.1 (GCC) 20200328
configuration: --enable-gpl --enable-version3 --enable-sdl2 --enable-fontconfig --enable-gnutls --enable-iconv --enable-libass --enable-libdav1d --enable-libbluray --enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libsrt --enable-libtheora --enable-libtwolame --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libzimg --enable-lzma --enable-zlib --enable-gmp --enable-libvidstab --enable-libvmaf --enable-libvorbis --enable-libvo-amrwbenc --enable-libmysofa --enable-libspeex --enable-libxvid --enable-libaom --disable-w32threads --enable-libmfx --enable-ffnvcodec --enable-cuda-llvm --enable-cuvid --enable-d3d11va --enable-nvenc --enable-nvdec --enable-dxva2 --enable-avisynth --enable-libopenmpt --enable-amf
libavutil 56. 42.102 / 56. 42.102
libavcodec 58. 81.100 / 58. 81.100
libavformat 58. 42.101 / 58. 42.101
libavdevice 58. 9.103 / 58. 9.103
libavfilter 7. 79.100 / 7. 79.100
libswscale 5. 6.101 / 5. 6.101
libswresample 3. 6.100 / 3. 6.100
libpostproc 55. 6.100 / 55. 6.100
..........................................................................
c:>pip -V ItsAGramLive
pip 20.0.2 from c:\users\my\appdata\local\programs\python\python38-32\lib\site-packages\pip (python 3.8)

@harrypython
Copy link
Owner

c:>pip -V ItsAGramLive
pip 20.0.2 from c:\users\my\appdata\local\programs\python\python38-32\lib\site-packages\pip (python 3.8)

Sorry, I did a mistake when I ask for pip -V ItsAGramLive

The corret is: pip show ItsAGramLive

@ahmadd110
Copy link
Author

c:>pip show ItsAGramLive
Name: ItsAGramLive
Version: 0.2
Summary: Its A Gram Live is a Python script that create a Instagram Live and provide you a rtmp server and stream key to streaming using sofwares like OBS-Studio.
Home-page: https://github.com/harrypython/itsagramlive
Author: Harry Python
Author-email: harrypython@protonmail.com
License: GPL-3.0
Location: c:\users\my\appdata\local\programs\python\python38-32\lib\site-packages
Requires: requests, pyperclip, progress, setuptools
Required-by:
Send feedback
History
Saved
Community

@harrypython
Copy link
Owner

Sorry ☹️, I am not being able to reproduce your results.

Try to check the spaces of your code one last time, maybe debugging line by line (I recommend PyCharm)

As a last resort open a question on the stackoverflow.

@harrypython harrypython added the help wanted Extra attention is needed label Apr 24, 2020
@ahmadd110
Copy link
Author

Thank a lot for your efforts
in LevPasha/Instagram-API-python there is "assert api.startBroadcast(broadcast_id, sendNotification=SEND_NOTIFICATIONS)" before ffmpeg code. Doesn't that matter?

@harrypython
Copy link
Owner

No, the point is: I'm not able to reproduce your error/results and it's working for me 乁( •_• )ㄏ

@ahmadd110
Copy link
Author

Thank a lot

@shelomito12
Copy link

From #26 - @harrypython, is it possible to update this python script in order to stream using ffmpeg cli? I know you said that it's better to create 2 separate processes for this but in my case I can only do it using bash, but I think I will have an issue getting the Key (the only thing I need) since your tool calls an interactive CLI... By the time my bash script extracts the Key, it might leave the IG session and the Key won't be valid anymore (?)

@shelomito12
Copy link

How to add code to the following simple script in order to just print the Server Key?

from ItsAGramLive import ItsAGramLive

# live = ItsAGramLive()

live = ItsAGramLive(
    username='foo',
    password='bar'
)

live.start()

For example, I just need 17866777868136769?s_hv=0&s_sw=0&s_vt=ig&a=Abw768iHvM9bumF0 printed to the output:

Let's do it!
You'r logged in
Broadcast ID: {}
* Broadcast ID: 17866777868136769
* Server URL: rtmps://live-upload.instagram.com:443/rtmp/
* Server Key: 17866777868136769?s_hv=0&s_sw=0&s_vt=ig&a=Abw768iHvM9bumF0
Could not find a copy/paste mechanism for your system
Press Enter after your setting your streaming software.
command> Available commands:
         "stop"
         "mute comments"
         "unmute comments"
         "info"
         "viewers"
         "comments"
         "chat"
         "wave"

command> 

@maxwol55
Copy link

`import json
import subprocess

from ItsAGramLive import ItsAGramLive

FILE_PATH = "/path/to/the/file/you/want/to/streaming"

live = ItsAGramLive()

broadcast_id = live.create_broadcast()

ffmpeg_cmd = "ffmpeg -rtbufsize 256M -re -i '{file}' -acodec libmp3lame -ar 44100 -b:a 128k -pix_fmt yuv420p "
"-profile:v baseline -s 720x1280 -bufsize 6000k -vb 400k -maxrate 1500k -deinterlace -vcodec libx264 "
"-preset veryfast -g 30 -r 30 -f flv '{stream_url}'"
.format(file=FILE_PATH, stream_url=live.LastJson['upload_url'])

data = json.dumps({'_uuid': live.uuid,
'_uid': live.username_id,
'should_send_notifications': int(live.sendNotification),
'_csrftoken': live.token})

if live.send_request(endpoint='live/' + str(broadcast_id) + '/start/', post=live.generate_signature(data)):

print('CTRL+C to quit.')
try:
    subprocess.call(ffmpeg_cmd, shell=True)
except KeyboardInterrupt:
    pass
except Exception as error:
    print(error)

live.end_broadcast(broadcast_id)`

version 1.4.1 does not work.
Please could you share a code that works in 1.4.1. Thank you

harrypython added a commit that referenced this issue Nov 24, 2020
@harrypython
Copy link
Owner

I put an example in the readme, let me know if works

@rdxshubham
Copy link

-deinterlace in FFmpeg is deprecated

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
help wanted Extra attention is needed question Further information is requested
Projects
None yet
Development

No branches or pull requests

5 participants