Here is my code:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from pydub import AudioSegment
import os
from urllib.parse import urlparse, parse_qs, unquote
from pytube import YouTube# misc
import urllib.request
from moviepy.editor import *
import eyed3
import time
class ConvertToMp3:
def convert(self,filename):
path_list = filename.split("/")
filename = path_list[len(path_list)-1]
path_list.remove(filename)
if(len(path_list)!=0 and path_list[0]==""):
path_list.remove(path_list[0])
path = ""
for folder in path_list:
path = path+"/"+folder
extension = filename.split(".")[1]
if path!="":
audio = AudioSegment.from_file(path+"/"+filename, format=extension)
else:
audio = AudioSegment.from_file(filename, format=extension)
audio.export("output files/"+filename.split(".")[0]+".mp3", format="mp3")
class ConvertFromYoutube:
def download(self,video_url,**options):
video_id = parse_qs(urlparse(video_url).query)['v'][0]
video = YouTube('https://www.youtube.com/watch?v='+video_id)
video.streams.get_by_itag(18).download("output files")
title = video.title
#print(title)
thumbnail = video.thumbnail_url
thumbnail_extension = thumbnail.split(".")
thumbnail_extension = thumbnail_extension[len(thumbnail_extension)-1]
urllib.request.urlretrieve(thumbnail, "output files/"+title+"."+thumbnail_extension)
self.save_as_mp3(title,"song_artist","song_album","song_album_artist","*****")
def save_as_mp3(self,song_title,song_artist,song_album,song_album_artist,song_rating):
video = VideoFileClip(os.path.join("output files",song_title+".mp4"))
video.audio.write_audiofile(os.path.join("output files",song_title+".mp3"))
audiofile = eyed3.load(os.path.join("output files",song_title+".mp3"))
audiofile.tag.artist = song_artist
audiofile.tag.album = song_album
audiofile.tag.album_artist = song_album_artist
audiofile.tag.title = song_title
print(audiofile.info.time_secs)
audiofile_duration = time.strftime('%H:%M:%S', time.gmtime(audiofile.info.time_secs))
print(audiofile.info.time_secs)
print(audiofile_duration)
audiofile.tag.save()
#test
#converter = ConvertToMp3()
#converter.convert("/home/chris/Μουσική/Απολυτίκιο Τριών Ιεραρχών.wav")
youtube = ConvertFromYoutube()
youtube.download("https://www.youtube.com/watch?v=JuYeHPFR3f0")
The time of pokemon theme song youtube video is: 3 minutes and 21 seconds.
The same information from file properties:
But print(audiofile.info.time_secs)
Prints out 405.62361067503923. That's wrong, so the calculation audiofile_duration = time.strftime('%H:%M:%S', time.gmtime(audiofile.info.time_secs)) is also wrong.
How can i fix that?
Thanks in advance,
Chris Pappas
Edit:
object_methods = [attr for attr in dir(audiofile.info) if not callable(getattr(audiofile.info, attr)) and not attr.startswith("__")]
print(object_methods)
['bit_rate', 'bit_rate_str', 'lame_tag', 'mode', 'mp3_header', 'sample_freq', 'size_bytes', 'time_secs', 'vbri_header', 'xing_header']
I found the solution here:
Finding the length of an mp3 file
But if it not possible to use so many libraries feel free for another answer.
Related
When using my code bellow (It turns YouTube videos into ASCII with audio) The latency between the audio and video grows bigger each frame (I have tried many different wait times) I was wondering if there is a way to change the code to make it so the wait key changes depending on how much latency there is. I have only been coding for 6 months so sorry if there is any bad code.
import pytube
import os
import cv2
import PIL.Image
import winsound
from moviepy.editor import *
from pydub import AudioSegment
import threading
import time
##################################################
# downloads the youtube video and lets you input the path for where it should be saved
url = input ("Enter the you youtube url: \n\n")
path = input ("Enter the path where you want the youtube video to be saved: \n\n")
try:
youtube = pytube.YouTube(url)
streams = youtube.streams.all()
video = youtube.streams.get_highest_resolution()
video.download(path)
print ("Done!")
except:
print ("\nYoutube video has coppy righted material so it can not be downloaded. Try again with a different video")
##################################################
#locates all the files with the file extension .mp4
for root, dirs, files in os.walk(path):
for file in files:
if file.endswith(".mp4"):
file_name = (file)
file_path = (os.path.join(root,file))
print (file_name)
print (file_path)
##################################################
mp3_file = (path+"\\")
mp3_file = (mp3_file+"audio.mp3")
mp4_file = (path+"\\")
mp4_file = (mp4_file+file_name)
VideoClip = VideoFileClip(mp4_file)
audioclip = VideoClip.audio
audioclip.write_audiofile(mp3_file)
audioclip.close()
VideoClip.close()
sound = AudioSegment.from_mp3(mp3_file)
sound.export(path+"/audio.wav", format = "wav")
##################################################
def a():
# Ascii characters used to create the output
ASCII_CHARS = ["#", "#", "S", "%", "?", "*", "+", ";", ":", ",", "."]
def resized_gray_image(image ,new_width=80):
width,height = image.size
aspect_ratio = height/width
new_height = int(aspect_ratio * new_width)
resized_gray_image = image.resize((new_width,new_height)).convert('L')
return resized_gray_image
def pix2chars(image):
pixels = image.getdata()
characters = "".join([ASCII_CHARS[pixel//25] for pixel in pixels])
return characters
def generate_frame(image,new_width=80):
new_image_data = pix2chars(resized_gray_image(image))
total_pixels = len(new_image_data)
ascii_image = "\n".join([new_image_data[index:(index+new_width)] for index in range(0, total_pixels, new_width)])
sys.stdout.write(ascii_image)
os.system('cls' if os.name == 'nt' else 'clear')
cap = cv2.VideoCapture(mp4_file)
print (cap)
try:
while True:
ret,frame = cap.read()
cv2.imshow("frame",frame)
generate_frame(PIL.Image.fromarray(frame))
cv2.waitKey(1)
except:
threading.Thread(target=c).start()
##################################################
def b():
winsound.PlaySound(path+"/audio.wav",winsound.SND_FILENAME)
##################################################
def c ():
os.remove (mp3_file)
os.remove (mp4_file)
os.remove (path+"/audio.wav")
threading.Thread(target=a).start()
threading.Thread(target=b).start()
I'm making a bot that downloads posts from a subreddit I selected, but I only want to download photos. My code already makes sure that the post is not a text but I'm not able to check if the video or not. If the post is a video, the program should just skip it.
Here is my code so far:
from InstagramAPI import InstagramAPI
import praw
import requests
import urllib.request
import time
import keyboard
from PIL import Image
import math
#make a reddit acount and look up how to find this stuff. its called PRAW
reddit = praw.Reddit(client_id='***',
client_secret='***',
username='',
password='',
user_agent='chrome')
def DLimage(url, filePath, fileName):
fullPath = filePath + fileName + '.jpg'
urllib.request.urlretrieve(url, fullPath)
#folder path to store downloaded images
filePath = "/Users/***/AppBot/WTF/"
subreddit = reddit.subreddit('videos') #subreddit to take images from
waitTime = 2 #to prevent reddit badgateway error. DONt change
numRounds = 100 #how many posts
postFrequency = 600 # how often to post in seconds.
numPics = 100 #how many pics per post
for x in range(numRounds):
new_memes = subreddit.top('all') #.hot/.rising/.new reddit sorting algorithm
authors = []
photoAlbum = []
print("Round/post number:", x)
for subbmission in new_memes:
if subbmission.preview == True: #checking if post is only text.
#print("Post was text, skipping to next post.")
pass
else:
continue
url = subbmission.url
time.sleep(waitTime)
fileName = str(subbmission)
fullPath = filePath + fileName + '.jpg'
#print(fullPath)
time.sleep(waitTime)
#print(url)
try:
DLimage(url, filePath, fileName)
except:
print("scratch that, next post.")
continue
time.sleep(waitTime)
img = Image.open(fullPath)
width, height = img.size
#img = img.resize((1000, 1020), Image.NEAREST) #image resize. width/height
img = img.convert("RGB")
img.save(fullPath)
time.sleep(postFrequency)
This is my first time posting a question so pardon any mistakes. I'm trying to write a script that will do face_recognition and save the video file at the same time and running into I think latency issues. When there isn't a face to detect it saves the video file fine. When there is a face though it seems to get every other frame. I feel like that is because it's doing computations for finding the face which prevents it from saving the next frame. Is there a way around this? maybe threading or multiprocessing?
import face_recognition as fr
import os
import face_recognition
import numpy as np
import cv2
def get_encoded_faces():
encoded = {}
for dirpath, dnames, fnames in os.walk("./faces"):
for f in fnames:
if f.endswith(".jpg") or f.endswith(".png"):
face = fr.load_image_file("faces/" + f)
encoding = fr.face_encodings(face)[0]
encoded[f.split(".")[0]] = encoding
return encoded
def unknown_image_encoded(img):
face = fr.load_image_file("faces/" + img)
encoding = fr.face_encodings(face)[0]
return encoding
faces = get_encoded_faces()
faces_encoded = list(faces.values())
known_face_names = list(faces.keys())
def FindFace(img):
face_locations = face_recognition.face_locations(img)
unknown_face_encodings = face_recognition.face_encodings(img, face_locations)
face_names = []
for face_encoding in unknown_face_encodings:
matches = face_recognition.compare_faces(faces_encoded, face_encoding)
name = "Unknown"
face_distances = face_recognition.face_distance(faces_encoded, face_encoding)
best_match_index = np.argmin(face_distances)
if matches[best_match_index]:
name = known_face_names[best_match_index]
face_names.append(name)
#cv2.imwrite('final_image.png',img)
video_capture = cv2.VideoCapture(1)
fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('output.avi',cv2.VideoWriter_fourcc('M','J','P','G'), 20.0, (640,480))
if not video_capture.isOpened():
raise Exception("Could not open video device")
while(video_capture.isOpened()):
ret, frame = video_capture.read()
out.write(frame)
#cv2.imshow('Video', frame)
FindFace(frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
video_capture.release()
cv2.destroyAllWindows()
import numpy as np
import os
import random
from six.moves import cPickle as pickle
from tensorflow.python.platform import gfile
import glob
import TensorflowUtils as utils
DATA_URL = 'http:\\data.csail.mit.edu\\places\\ADEchallenge\\ADEChallengeData2016.zip'
#download and read dataset
def read_dataset(data_dir):
pickle_filename = "MITSceneParsing.pickle"
pickle_filepath = os.path.join(data_dir, pickle_filename)
if not os.path.exists(pickle_filepath):
utils.maybe_download_and_extract(data_dir, DATA_URL, is_zipfile=True)
SceneParsing_folder = os.path.splitext(DATA_URL.split("/")[-1])[0]
result = create_image_lists(os.path.join(data_dir, SceneParsing_folder))
print ("Pickling ...")
with open(pickle_filepath, 'wb') as f:
pickle.dump(result, f, pickle.HIGHEST_PROTOCOL)
else:
print ("Found pickle file!")
with open(pickle_filepath, 'rb') as f:
result = pickle.load(f)
training_records = result['training']
validation_records = result['validation']
del result
return training_records, validation_records
train_records, valid_records = read_dataset('Data_zoo/MIT_SceneParsing')
print(len(train_records))
print(len(valid_records))
the result is:Found pickle file! 0 0
why the lens about train_records and valid_records are 0?
i don't know whree is wrong and how to correct it.
This code is right. The bug is in 'create_image_lists'.
Note this code in create_image_lists:
filename = os.path.splitext(f.split('/')[-1])[0]
This is no problem in Linux, but in windows, the separator is '\\', so you should modify this code to:
filename = os.path.splitext(f.split('\\')[-1])[0]
Then delete this file 'MITSceneParsing.pickle', and run read_dataset again.
I tried to convert PNG images to video by list images in directory
clips[]
for filename in os.listdir('.'):
if filename.endswith(".png"):
clips.append(ImageClip(filename))
Then convert it
video = concatenate(clips, method='compose')
video.write_videofile('test.mp4')
The error is:
Full code
import os
from moviepy.editor import *
clips = []
base_dir = os.path.realpath(".")
print(base_dir)
for filename in os.listdir('.'):
if filename.endswith(".png"):
clips.append(ImageClip(filename))
video = concatenate(clips, method='compose')
video.write_videofile('test.mp4')
I found another way to do it:
from moviepy.editor import *
img = ['1.png', '2.png', '3.png', '4.png', '5.png', '6.png',
'7.png', '8.png', '9.png', '10.png', '11.png', '12.png']
clips = [ImageClip(m).set_duration(2)
for m in img]
concat_clip = concatenate_videoclips(clips, method="compose")
concat_clip.write_videofile("test.mp4", fps=24)
And from current folder:
import os
import glob
from natsort import natsorted
from moviepy.editor import *
base_dir = os.path.realpath("./images")
print(base_dir)
gif_name = 'pic'
fps = 24
file_list = glob.glob('*.png') # Get all the pngs in the current directory
file_list_sorted = natsorted(file_list,reverse=False) # Sort the images
clips = [ImageClip(m).set_duration(2)
for m in file_list_sorted]
concat_clip = concatenate_videoclips(clips, method="compose")
concat_clip.write_videofile("test.mp4", fps=fps)
This is how I did it using your initial code. The error you were seeing was due to not specifying set_duration for the clips. I also sorted the files in the directory so that the resulting mp4 is sequential (was not the case by default).
import os
from moviepy.editor import *
base_dir = os.path.realpath(".")
print(base_dir)
directory=sorted(os.listdir('.'))
print(directory)
for filename in directory:
if filename.endswith(".png"):
clips.append(ImageClip(filename).set_duration(1))
print(clips)
video = concatenate(clips, method="compose")
video.write_videofile('test1.mp4', fps=24)