Search code examples
pythonfacebookfacebook-graph-api

Video file too Small while trying to upload a reel on facebook API


i am trying to upload a reel (MP4, 16 seconds, and 9 MB) using facebook graph API, but i get the following error:

Failed to upload reel: {'error': {'message': 'The video file you tried to upload is too small. Please try again with a larger file.', 'type': 'OAuthException', 'code': 382, 'error_subcode': 1363022, 'is_transient': False, 'error_user_title': 'Video Too Small', 'error_user_msg': 'The video you tried to upload is too small. The minimum size for a video is 1 KB. Please try again with a larger file.', 'fbtrace_id': 'A0WVVSGWnXEfffdwrjFUENsJVC'}}

The code:

import requests
from datetime import datetime
import subprocess
import os

def human_readable_to_timestamp(date_string):
    try:
        # Convert the human-readable date string to a datetime object
        dt_object = datetime.strptime(date_string, '%Y-%m-%d %H:%M:%S')
        # Convert the datetime object to UNIX timestamp
        timestamp = int(dt_object.timestamp())
        return timestamp
    except ValueError:
        print("Invalid date format. Please provide the date in the format: YYYY-MM-DD HH:MM:SS")
        return None

def extract_frame(video_path, time, output_path):
    # Use ffmpeg to extract a frame from the video at the specified time
    cmd = [
        'ffmpeg', '-y',
        '-i', video_path,
        '-ss', str(time),
        '-vframes', '1',
        '-q:v', '2',  # Set quality (1-31, 1 being highest)
        output_path
    ]
    subprocess.run(cmd, check=True)

def upload_reel_with_thumbnail(video_path, thumbnail_path, access_token, file_size, target_file_size, scheduled_publish_time=None):

    
    # Endpoint for uploading videos
    url = 'https://graph.facebook.com/v15.0/me/videos'

    if file_size < target_file_size:
        # Pad the file with zeros to reach the target file size
        with open(video_path, 'ab') as video_file:
            video_file.write(b'\0' * (target_file_size - file_size))
            file_size = target_file_size  # Update the file size after padding
    print (file_size)
    # Video data
    video_data = {
        'access_token': access_token,
        #'file_url': video_path,
        'description': 'Check out this amazing reel!',
        'file_size': file_size,
        'published': 'false'
        # Additional parameters can be added here as needed
    }

    # If scheduling time is provided, add it to the request
    if scheduled_publish_time:
        video_data['scheduled_publish_time'] = human_readable_to_timestamp(scheduled_publish_time)

    try:
        # Sending POST request to upload the video
        files = {'file': video_path}
        response = requests.post(url, data=video_data, files=files)
        response_json = response.json()

        # Check if the upload was successful
        if 'id' in response_json:
            reel_id = response_json['id']
            print("Reel uploaded successfully! Reel ID:", reel_id)

            # Upload the thumbnail
            upload_thumbnail(reel_id, thumbnail_path, access_token)

            # If scheduling time is provided, schedule the reel
            if scheduled_publish_time:
                schedule_reel(reel_id, scheduled_publish_time, access_token)
        else:
            print("Failed to upload reel:", response_json)
    except Exception as e:
        print("An error occurred:", str(e))

def upload_thumbnail(reel_id, thumbnail_path, access_token):
    # Endpoint for uploading thumbnail
    url = f'https://graph.facebook.com/v15.0/{reel_id}'
    
    # Thumbnail data
    files = {'thumb': open(thumbnail_path, 'rb')}
    params = {'access_token': access_token}

    try:
        # Sending POST request to upload the thumbnail
        response = requests.post(url, files=files, params=params)
        response_json = response.json()

        # Check if the thumbnail upload was successful
        if 'success' in response_json and response_json['success']:
            print("Thumbnail uploaded successfully!")
        else:
            print("Failed to upload thumbnail:", response_json)
    except Exception as e:
        print("An error occurred:", str(e))

def schedule_reel(reel_id, scheduled_publish_time, access_token):
    # Endpoint for scheduling the reel
    url = f'https://graph.facebook.com/v15.0/{reel_id}'

    # Schedule data
    data = {
        'access_token': access_token,
        'published': 'false',
        'scheduled_publish_time': scheduled_publish_time
    }

    try:
        # Sending POST request to schedule the reel
        response = requests.post(url, data=data)
        response_json = response.json()

        # Check if scheduling was successful
        if 'id' in response_json:
            print("Reel scheduled successfully!")
        else:
            print("Failed to schedule reel:", response_json)
    except Exception as e:
        print("An error occurred:", str(e))


# Example usage
if __name__ == "__main__":
    # Path to the video file
    video_path = '55.mp4'
            
    file_size = os.path.getsize(video_path)
    target_file_size = 10 * 1024  # 30 KB
    print (file_size)
    # Path to the thumbnail image
    thumbnail_path = 'thumbnails/55.jpg'
    
    extract_frame(video_path, 6, thumbnail_path)

    # Facebook Access Token
    access_token = 'xxxxx'

    # Scheduled publish time (human-readable format)
    scheduled_publish_time = '2024-04-10 15:30:00'  # Example: April 10, 2024, 15:30:00 UTC

    # Call the function to upload the reel with the extracted thumbnail and schedule it
    upload_reel_with_thumbnail(video_path, thumbnail_path, access_token, file_size, target_file_size, scheduled_publish_time)
    
    print ("done")

Any idea :(?


Solution

  • Your implementation does seem to use some parameter names not found in the API documentation, the video file for example should be part of the data instead of files and called source. I suggest double-checking the expected parameters/request types and responses directly from there. Additionally this uses the API version v15.0 when the newest one is v19.0, you might want to upgrade your code to use it.