pytube (python) video stops playing video after few seconds - python

I have been using pytube to create my youtube video downloader and after the video is done downloading and compiling and i play it, it plays for only a few seconds then just displays a still image while the audio continues in background
These are the functions in file "module.py"
import pytube
from moviepy.editor import *
import os.path
def video(link):
yt = pytube.YouTube(link)
streamlist = []
for stream in yt.streams.filter():
streamlist.append(stream)
finalstreamlist = []
for i in streamlist:
if i.resolution == "1080p" and i.mime_type == "video/mp4":
finalstreamlist.append(i)
stream = yt.streams.get_by_itag(finalstreamlist[0].itag)
stream.download(r"C:\Users\pc\PycharmProjects\youtube")
return [stream.title, yt.length]
def audio(link):
yt = pytube.YouTube(link)
streamlist = []
for stream in yt.streams.filter():
streamlist.append(stream)
finalstreamlist = []
for i in streamlist:
if i.mime_type == "audio/mp4":
finalstreamlist.append(i)
stream = yt.streams.get_by_itag(finalstreamlist[0].itag)
stream.download(r"C:\Users\pc\PycharmProjects\youtube", "Audio.mp4")
return ["Audio.mp4",yt.length]
def mixer(video,audio,title):
videoclip = VideoFileClip(video)
audioclip = AudioFileClip(audio)
videoclip2 = videoclip.set_audio(audioclip)
videoclip2.write_videofile(title)
And this is the "main.py" file:
from modules import *
import time
link = "https://www.youtube.com/watch?v=CLk7A7HXhYQ"
vtitle = video(link)[0] + ".mp4"
atitle = audio(link)[0]
print("Files Downloaded")
time.sleep(1)
print("Compiling")
mixer(vtitle,atitle,vtitle)
print("FileDone")

I tried your code and it downloads video file correctly but problem is when it mixs video and audio.
I think problem it that it writes new video with the same name as original video - probably it doesn't load old video to memory but it reads it all time from file - and this makes conflict.
I think you should write new video with new (temporary) filename and later rename it to expected name. Or you should download video with temporary name (i.e. video.mp4)
My code which I used for tests
import pytube
from moviepy.editor import *
import os
BASE = os.path.dirname(os.path.abspath(__file__))
def video(link):
yt = pytube.YouTube(link)
finalstreamlist = yt.streams.filter(resolution='1080p', mime_type='video/mp4')
itag = finalstreamlist[0].itag
print('video itag:', itag)
stream = yt.streams.get_by_itag(itag)
stream.download(os.path.join(BASE, 'youtube'), 'video.mp4')
return [os.path.join(BASE, 'youtube/video.mp4'), stream.title, yt.length]
def audio(link):
yt = pytube.YouTube(link)
finalstreamlist = yt.streams.filter(mime_type='video/mp4')
itag = finalstreamlist[0].itag
print('audio itag:', itag)
stream = yt.streams.get_by_itag(itag)
stream.download(os.path.join(BASE, 'youtube'), 'audio.mp4')
return [os.path.join(BASE, 'youtube/audio.mp4'), stream.title, yt.length]
def mixer(video, audio, title):
videoclip = VideoFileClip(video)
audioclip = AudioFileClip(audio)
new_videoclip = videoclip.set_audio(audioclip)
new_videoclip.write_videofile(title)
# --- main ---
link = 'https://www.youtube.com/watch?v=CLk7A7HXhYQ'
print('Downloading')
v = video(link)
a = audio(link)
print('Downloaded')
print('Compiling')
output = os.path.join(BASE, v[1] + '.mp4')
mixer(v[0], a[0], output)
print('Compilied')

Related

concatenate_videoclips can't handle image clips with audio attached to them

So I am creating this scrip that concatenates videos of images with audio attached to them, I previously created the videos with another python file by adding audio to the image and converting it into video.
The videos work individually but when I concatenate them, the final video glitches and looks weird
Code:
from moviepy.editor import *
clip1 = VideoFileClip("final_video0.mp4")
clip2 = VideoFileClip("final_video1.mp4")
clip3 = VideoFileClip("final_video2.mp4")
clip4 = VideoFileClip("final_video3.mp4")
clip5 = VideoFileClip("final_video4.mp4")
clip6 = VideoFileClip("final_video5.mp4")
clip7 = VideoFileClip("final_video6.mp4")
clip8 = VideoFileClip("final_video7.mp4")
clip9 = VideoFileClip("final_video8.mp4")
clip10 = VideoFileClip("final_video9.mp4")
final = concatenate_videoclips([clip1, clip2, clip3, clip4, clip5, clip6])
final.write_videofile("merged.mp4")

Zoom and crop a pdf document using PyMuPDF fitz and saving as pdf

I am trying to crop a pdf within and lambda and save the file. Ideally I just want to zoom in as otherwise the OCR package does not recognize some of the fonts. The rectangle I am using just seems to shift the margins versus actually cropping or zooming in.
Thanks!
import os
import json
import boto3
from urllib.parse import unquote_plus
import fitz, sys
from io import BytesIO
OUTPUT_BUCKET_NAME = os.environ["OUTPUT_BUCKET_NAME"]
OUTPUT_S3_PREFIX = os.environ["OUTPUT_S3_PREFIX"]
SNS_TOPIC_ARN = os.environ["SNS_TOPIC_ARN"]
SNS_ROLE_ARN = os.environ["SNS_ROLE_ARN"]
def lambda_handler(event, context):
if event:
file_obj = event["Records"][0]
bucketname = str(file_obj["s3"]["bucket"]["name"])
filename = unquote_plus(str(file_obj["s3"]["object"]["key"]))
doc = fitz.open()
s3 = boto3.resource('s3')
obj = s3.Object(bucketname, filename)
fs = obj.get()['Body'].read()
pdf=fitz.open("pdf", stream=BytesIO(fs))
rect=fitz.Rect(50, 50, 545, 792)
page = pdf[0]
page1 = doc.new_page(width = rect.width, # new page with ...
height = rect.height)
page1.show_pdf_page(rect, pdf, 0)
new_bytes = doc.write()
bucketname1='modified'
s3.Bucket(bucketname1).put_object(Key=filename, Body=new_bytes)

I want to process bulk of wav files at a time and convert them all into text like hindi english tamil etc by using python programming

import speech_recognition as sr
import os
from pydub import AudioSegment
from pydub.silence import split_on_silence
r = sr.Recognizer()
def get_large_audio_transcription(path,):
"""
Splitting the large audio file into chunks
and apply speech recognition on each of these chunks
"""
sound = AudioSegment.from_wav(path)
chunks = split_on_silence(sound,
min_silence_len = 500,
silence_thresh = sound.dBFS-16,
keep_silence=500,
)
folder_name = "audio-chunks"
if not os.path.isdir(folder_name):
os.mkdir(folder_name)
whole_text = ""
for i, audio_chunk in enumerate(chunks, start=1):
chunk_filename = os.path.join(folder_name, f"chunk{i}.wav")
audio_chunk.export(chunk_filename, format="wav")
with sr.AudioFile(chunk_filename) as source:
audio_listened = r.record(source)
try:
text = r.recognize_google(audio_listened,language="hi-IN")
except sr.UnknownValueError as e:
print("Error:", str(e))
else:
text = f"{text.capitalize()}. "
print(chunk_filename, ":", text)
whole_text += text
return whole_text
path = "G:\ezimex\audiowav\wav1.wav"
print("\nFull text:",get_large_audio_transcription(path))
Using this code I pass one audio at a time but it takes to much time to process all audio one by one into text.
I want to process all wav files process at once and covert all into text. please help me to solve it using python. the all audio files stores in a folder audiowav.
How to process these bulked files at once using python and convert into text?

YouTube video Downloader python

I made a youtube video download Manager. It download a video but i am facing one issue when i download same video, it doesn't download it again. how can i download it again with same title like pic.png and send pic1.png. How can i do that?
def Download(self):
video_url = self.lineEdit.text()
save_location = self.lineEdit_2.text()
if video_url == '' or save_location == '':
QMessageBox.warning(self, "Data Error", "Provide a Valid Video URL or save Location")
else:
video = pafy.new(video_url)
video_stream = video.streams
video_quality = self.comboBox.currentIndex()
download = video_stream[video_quality].download(filepath=save_location, callback=self.Handel_Progress, )
Ok, this one is interesting.
The real problem begins here.
download = video_stream[video_quality].download(filepath=save_location, callback=self.Handel_Progress, )
Here, you are calling download function of video_stream object which takes filepath as an argument for file location but does not take the filename, because, obviously, the file would be saved with the actual name.
Root Cause of your problem:
If you look into the definition of download function, you would find that if a file exists with the same name, it would not download the file at all.
Now comes the part, how do you make sure it downloads, no matter what:
There are two things you need to do:
Check if a file with same name exists or not, and if does, then add 1 in the end of the file name just before the extension. So if abc.mp4 exists, then save abc1.mp4.
[I will tell you how to handle the scenario when abc.mp4, abc1.mp4 and so on exists, but for now, let's get back to the problem.]
How to pass the file name (abc1.mp4) to the download method?
Following piece of code would handle both.
I have added comments for your understanding.
import os
import re
import pafy
from pafy.util import xenc
# this function is used by pafy to generate file name while saving,
# so im using the same function to get the file name which I will use to check
# if file exists or not
# DO NOT CHANGE IT
def generate_filename(title, extension):
max_length = 251
""" Generate filename. """
ok = re.compile(r'[^/]')
if os.name == "nt":
ok = re.compile(r'[^\\/:*?"<>|]')
filename = "".join(x if ok.match(x) else "_" for x in title)
if max_length:
max_length = max_length + 1 + len(extension)
if len(filename) > max_length:
filename = filename[:max_length - 3] + '...'
filename += "." + extension
return xenc(filename)
def get_file_name_for_saving(save_location, full_name):
file_path_with_name = os.path.join(save_location, full_name)
# file exists, add 1 in the end, otherwise return filename as it is
if os.path.exists(file_path_with_name):
split = file_path_with_name.split(".")
file_path_with_name = ".".join(split[:-1]) + "1." + split[-1]
return file_path_with_name
def Download(self):
video_url = self.lineEdit.text()
save_location = self.lineEdit_2.text()
if video_url == '' or save_location == '':
QMessageBox.warning(self, "Data Error", "Provide a Valid Video URL or save Location")
else:
# video file
video = pafy.new(video_url)
# available video streams
video_stream = video.streams
video_quality = self.comboBox.currentIndex()
# video title/name
video_name = video.title
# take out the extension of the file from video stream
extension = video_stream[video_quality].extension
# fullname with extension
full_name = generate_filename(video_name, extension)
final_path_with_file_name = get_file_name_for_saving(save_location, full_name)
download = video_stream[video_quality].download(filepath=final_path_with_file_name,
callback=self.Handel_Progress, )
Let me know if you face any issues.

Recording youtube live stream to file in python

I want to record youtube live stream and save it to file using python.
I tried with pytube library but it probably works for videos, not for live streams.
I want to record stream and save it to file with video format as avi or something like this.
Modification based on #wownis 's answer.
(I tried that answer, however, it doesn't work.)
# pip install urllib
# pip install m3u8
# pip install streamlink
import urllib
import m3u8
import streamlink
def get_stream(url):
"""
Get upload chunk url
"""
streams = streamlink.streams(url)
stream_url = streams["best"]
m3u8_obj = m3u8.load(stream_url.args['url'])
return m3u8_obj.segments[0]
def dl_stream(url, filename, chunks):
"""
Download each chunks
"""
pre_time_stamp = 0
for i in range(chunks+1):
stream_segment = get_stream(url)
cur_time_stamp = \
stream_segment.program_date_time.strftime("%Y%m%d-%H%M%S")
if pre_time_stamp == cur_time_stamp:
pass
else:
print(cur_time_stamp)
file = open(filename + '_' + str(cur_time_stamp) + '.ts', 'ab+')
with urllib.request.urlopen(stream_segment.uri) as response:
html = response.read()
file.write(html)
pre_time_stamp = cur_time_stamp
url = "https://www.youtube.com/watch?v=2U3JnFbD-es"
dl_stream(url, "live", 15)
Output like this:
./
live_20200713-103739.ts
live_20200713-103744.ts
...
I found a solution and i put my code in python:
import urllib
import m3u8
import streamlink
def record_stream(url,filename,iterations):
last_part = 0
for i in range(iterations+1):
streams = streamlink.streams(url)
stream_url = streams["best"]
print(stream_url.args['url'])
m3u8_obj = m3u8.load(stream_url.args['url'])
previous_part_time = last_part
last_part = m3u8_obj.segments[-1].program_date_time
if i >= 1:
for j in range(1, len(m3u8_obj.segments)):
if m3u8_obj.segments[-j].program_date_time == previous_part_time:
break
print(j)
file = open(filename + ".ts", "ab+")
for i in range(j-1,0,-1):
with urllib.request.urlopen(m3u8_obj.segments[-i].uri) as response:
html = response.read()
file.write(html)
url = "https://www.youtube.com/watch?v=BgKGctL0u1U"
record_stream(url,"file",10)
10 means 10 iterations if chunks have 2s it means that records 20s of stream

Categories