Encode a Local Video Library
Encode all the videos inside a local folder on you PC and save them back to it.
In this tutorial, you will learn how to select all the videos stored in a local folder on your computer, upload them to ByteNite, and let ByteNite encode them for you.
You will be able to download the encoded videos and save them back to your computer or to a cloud storage solution such as S3 or Dropbox.
Troubleshooting tip
In Python, you can diagnose API errors with
response.raise_for_status()
.Please check out the HTTP status codes in the API Reference for further details.
1. Get an access token
To begin, use your API key to obtain an access token.
import requests, json
import os
verbose = True
verboseprint = print if verbose else lambda *a, **k: None
api_key = 'BYTENITE_API_KEY' # << Paste here your API key
response = requests.post('https://api.bytenite.com/v1/auth/access_token',
json={"apiKey": api_key})
access_token = response.json()['token'] # Your access token will be saved in this variable
2. Prepare your local folder
Specify the path to the folder on your computer where your videos are stored. You don't need to list your videos one by one; the following script will do that for you. The list sources
will contain the paths to your videos.
my_dir = 'YOUR_FOLDER_PATH' # << Specify your local folder path here
# Search for videos in your folder
video_file_extensions = ('.264', '.3g2', '.3gp', '.3gp2', '.3gpp', '.3gpp2', '.3mm', '.3p2', '.60d', '.787', '.89', '.aaf', '.aec', '.aep', '.aepx', '.aet', '.aetx', '.ajp', '.ale', '.am', '.amc', '.amv', '.amx', '.anim', '.aqt', '.arcut', '.arf', '.asf', '.asx', '.avb', '.avc', '.avd', '.avi', '.avp', '.avs', '.avs', '.avv', '.axm', '.bdm', '.bdmv', '.bdt2', '.bdt3', '.bik', '.bin', '.bix', '.bmk', '.bnp', '.box', '.bs4', '.bsf', '.bvr', '.byu', '.camproj', '.camrec', '.camv', '.ced', '.cel', '.cine', '.cip', '.clpi', '.cmmp', '.cmmtpl', '.cmproj', '.cmrec', '.cpi', '.cst', '.cvc', '.cx3', '.d2v', '.d3v', '.dat', '.dav', '.dce', '.dck', '.dcr', '.dcr', '.ddat', '.dif', '.dir', '.divx', '.dlx', '.dmb', '.dmsd', '.dmsd3d', '.dmsm', '.dmsm3d', '.dmss', '.dmx', '.dnc', '.dpa', '.dpg', '.dream', '.dsy', '.dv', '.dv-avi', '.dv4', '.dvdmedia', '.dvr', '.dvr-ms', '.dvx', '.dxr', '.dzm', '.dzp', '.dzt', '.edl', '.evo', '.eye', '.ezt', '.f4p', '.f4v', '.fbr', '.fbr', '.fbz', '.fcp', '.fcproject', '.ffd', '.flc', '.flh', '.fli', '.flv', '.flx', '.gfp', '.gl', '.gom', '.grasp', '.gts', '.gvi', '.gvp', '.h264', '.hdmov', '.hkm', '.ifo', '.imovieproj', '.imovieproject', '.ircp', '.irf', '.ism', '.ismc', '.ismv', '.iva', '.ivf', '.ivr', '.ivs', '.izz', '.izzy', '.jss', '.jts', '.jtv', '.k3g', '.kmv', '.ktn', '.lrec', '.lsf', '.lsx', '.m15', '.m1pg', '.m1v', '.m21', '.m21', '.m2a', '.m2p', '.m2t', '.m2ts', '.m2v', '.m4e', '.m4u', '.m4v', '.m75', '.mani', '.meta', '.mgv', '.mj2', '.mjp', '.mjpg', '.mk3d', '.mkv', '.mmv', '.mnv', '.mob', '.mod', '.modd', '.moff', '.moi', '.moov', '.mov', '.movie', '.mp21', '.mp21', '.mp2v', '.mp4', '.mp4v', '.mpe', '.mpeg', '.mpeg1', '.mpeg4', '.mpf', '.mpg', '.mpg2', '.mpgindex', '.mpl', '.mpl', '.mpls', '.mpsub', '.mpv', '.mpv2', '.mqv', '.msdvd', '.mse', '.msh', '.mswmm', '.mts', '.mtv', '.mvb', '.mvc', '.mvd', '.mve', '.mvex', '.mvp', '.mvp', '.mvy', '.mxf', '.mxv', '.mys', '.ncor', '.nsv', '.nut', '.nuv', '.nvc', '.ogm', '.ogv', '.ogx', '.osp', '.otrkey', '.pac', '.par', '.pds', '.pgi', '.photoshow', '.piv', '.pjs', '.playlist', '.plproj', '.pmf', '.pmv', '.pns', '.ppj', '.prel', '.pro', '.prproj', '.prtl', '.psb', '.psh', '.pssd', '.pva', '.pvr', '.pxv', '.qt', '.qtch', '.qtindex', '.qtl', '.qtm', '.qtz', '.r3d', '.rcd', '.rcproject', '.rdb', '.rec', '.rm', '.rmd', '.rmd', '.rmp', '.rms', '.rmv', '.rmvb', '.roq', '.rp', '.rsx', '.rts', '.rts', '.rum', '.rv', '.rvid', '.rvl', '.sbk', '.sbt', '.scc', '.scm', '.scm', '.scn', '.screenflow', '.sec', '.sedprj', '.seq', '.sfd', '.sfvidcap', '.siv', '.smi', '.smi', '.smil', '.smk', '.sml', '.smv', '.spl', '.sqz', '.srt', '.ssf', '.ssm', '.stl', '.str', '.stx', '.svi', '.swf', '.swi', '.swt', '.tda3mt', '.tdx', '.thp', '.tivo', '.tix', '.tod', '.tp', '.tp0', '.tpd', '.tpr', '.trp', '.ts', '.tsp', '.ttxt', '.tvs', '.usf', '.usm', '.vc1', '.vcpf', '.vcr', '.vcv', '.vdo', '.vdr', '.vdx', '.veg','.vem', '.vep', '.vf', '.vft', '.vfw', '.vfz', '.vgz', '.vid', '.video', '.viewlet', '.viv', '.vivo', '.vlab', '.vob', '.vp3', '.vp6', '.vp7', '.vpj', '.vro', '.vs4', '.vse', '.vsp', '.w32', '.wcp', '.webm', '.wlmp', '.wm', '.wmd', '.wmmp', '.wmv', '.wmx', '.wot', '.wp3', '.wpl', '.wtv', '.wve', '.wvx', '.xej', '.xel', '.xesc', '.xfl', '.xlmv', '.xmv', '.xvid', '.y4m', '.yog', '.yuv', '.zeg', '.zm1', '.zm2', '.zm3', '.zmv')
your_videos = [item.name for item in os.scandir(my_dir) if item.is_file() and item.name.endswith(video_file_extensions)]
your_videos.sort()
# Prepare the filepaths
sources = [os.path.join(my_dir, v) for v in your_videos]
3. Generate the jobs
Create a new video encoding job for each of your_videos
. You will need to save the assigned job IDs in a list to be able to access them later.
Automation Disclaimer
The code below and the following will generate an encoding job for each video file contained in your folder. You might want to double-check that you've selected the right folder and number of videos, to avoid wasting ByteChips.
# Set your API request parameters
app_template = "[email protected]"
# Initialize the list of job IDs and set the job names
n = len(your_videos)
job_ids = ['']*n
job_names = [s[:min(s.rfind("."),25)] for s in your_videos] # << Give your jobs whatever names you like
# Generate n jobs
for i in range(n):
response = requests.post('http://api.bytenite.com/v1/customer/jobs',
json={"name": job_names[i], "templateId": app_template},
headers={'Authorization': access_token})
try:
job_ids[i] = response.json()['job']['id']
verboseprint(f"Job #{i} ({job_names[i]}) created - ID: {job_ids[i]}")
except:
print(f"CREATE ERROR: Job #{i} ({job_names[i]}): {response}")
4. Upload the videos
As also explained in "Encode a Local Video" guide, the local upload process with ByteNite requires three steps: retrieving a temporary URL from the data source setting response; uploading your video to the temporary URL; and notifying the server of the completed upload.
The following code automates this step for the n
video encoding jobs.
data_source_body = {
"dataSource": {
"dataSourceDescriptor": "file",
"params": {
"@type": "type.googleapis.com/bytenite.data_source.LocalFileDataSource"
}
},
"dataDestination": {
"dataSourceDescriptor": "bucket",
}
}
for i in range(n):
response1, response2, response3 = "", "", ""
# Set the data source and destination
response1 = requests.post(f'https://api.bytenite.com/v1/customer/jobs/datasource/{job_ids[i]}',
json=data_source_body,
headers={'Authorization': access_token})
try:
# Retrieve a temp URL from the datasource response
temp_url = response1.json()['job']['dataSource']['params']['tempUrl']
# Upload the video to the temp URL
verboseprint("Uploading...")
with open(sources[i], mode='rb') as f:
response2 = requests.put(temp_url, data=f, headers={'Content-Disposition': f'attachment; filename="{sources[i]}"'})
# Notify ByteNite about the completed upload
response3 = requests.post(f'http://api.bytenite.com/v1/customer/jobs/uploadcompleted/{job_ids[i]}',
json={},
headers={'Authorization': access_token})
verboseprint(f"Video #{i} ({job_names[i]}) uploaded")
except:
print(f'UPLOAD ERROR: Job #{i} ({job_names[i]}):')
print(f'datasource: {response1} | put: {response2} | upload completed: {response3}\n')
5. Configure the encoding parameters
Load a JSON file containing the video parameters for your video encoding jobs using one of our Templates.
# Load a video encoding template
with open("path_to_your_template.json") as venc_template: # << Paste the path to your template here
job_parameters = json.load(venc_template)
for i in range(n):
response = requests.post(f'https://api.bytenite.com/v1/customer/jobs/params/{job_ids[i]}',
json=job_parameters,
headers={'Authorization': access_token})
try:
response.raise_for_status()
verboseprint(f"Parameters for job #{i} ({job_names[i]}) set")
except:
print(f"PARAMETERS SETTING ERROR: Job #{i} ({job_names[i]}): {response}")
6. Start the jobs
Run your video encoding jobs.
for i in range(n):
response = requests.post(f'https://api.bytenite.com/v1/customer/jobs/run/{job_ids[i]}',
headers={'Authorization': access_token})
try:
response.raise_for_status()
verboseprint(f"Job #{i} ({job_names[i]}) started")
except:
print(f"RUN JOB ERROR: Job #{i} ({job_names[i]}): {response}")
7. Check the job statuses
Monitor the progress of your jobs and extract additional information if needed.
complete_count = 0
for i in range(n):
response = requests.get(f'https://api.bytenite.com/v1/customer/jobs/{job_ids[i]}',
headers={'Authorization': access_token})
complete_count += 1 if response.json()['job']['state'] == 'JOB_STATE_COMPLETE' else 0
verboseprint(f"Completed jobs: {complete_count}/{n}")
8. Download your outputs to a local folder
When your jobs are completed, you can access the links to the output videos and download them.
Please keep in mind that if you've chosen our temporary storage option as the data destination, your output will be accessible for 48 hours starting from the moment the job is completed.
# Set the filepath for saving your output videos
out_dir = os.path.join(my_dir, 'encoded/')
os.makedirs(out_dir, exist_ok=True)
for i in range(n):
# Get the results
response = requests.get(f'https://api.bytenite.com/v1/customer/jobs/{job_ids[i]}/results',
headers={'Authorization': access_token})
results = response.json()['results']
# Download the results from the temporary bucket and write them to your local directory
out_file = os.path.join(out_dir, results[0]['name'])
with open(out_file, 'wb') as out:
r = requests.get(results[0]['link'], allow_redirects=True)
out.write(r.content)
verboseprint(f'File {out_file} written')
That's it!
You've now successfully encoded a local video library using ByteNite. Happy encoding!
Updated 10 months ago