├── intro.mp4 ├── requirements.txt ├── CleanUp.py ├── README.md ├── License.txt ├── UploadOnYoutube.py ├── Google.py ├── main.py └── MakeVideo.py /intro.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neeleshpandey/AutomatedNewsChannel/HEAD/intro.mp4 -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | google_api_python_client 2 | google 3 | google_auth_oauthlib 4 | moviepy 5 | newsapi-python 6 | urllib3 7 | gTTS 8 | mutagen 9 | Pillow -------------------------------------------------------------------------------- /CleanUp.py: -------------------------------------------------------------------------------- 1 | import os 2 | import shutil 3 | def cleanUp(imgfolder,audfolder): 4 | shutil.rmtree(imgfolder[2::],ignore_errors=True) #To Delete All Downloaded Images 5 | shutil.rmtree(audfolder[2::],ignore_errors=True) #To Delete All Generated Audio 6 | shutil.rmtree("__pycache__",ignore_errors=True) #To Delete Cache formed in the process 7 | if os.path.exists("output.mp4"): 8 | os.remove("output.mp4") #To Delete Final Video After Uploading 9 | 10 | if __name__ == "__main__": 11 | cleanUp('./images/', 12 | './audio/' 13 | ) -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Automated NEWS Channel 2 | ##### This is a Piece of code that fetches news using an API and Converts it into a NEWS video 3 | 4 | ## Instructions 5 | 1. [Download](https://github.com/neeleshpandey/AutomatedNewsChannel/archive/refs/heads/master.zip) or Clone this Repository in your Local Environment 6 | 2. Download and install [`Python3`](https://www.python.org/downloads/) and [`pip`](https://pip.pypa.io/en/stable/installing/) 7 | 3. Install libraries with `pip3 install -r requirements.txt` or `python3 -m pip install -r requirements.txt` 8 | 4. Get the API of [NEWS API](https://newsapi.org/) , Its simple just Register Yourself and get the `KEY` 9 | 5. Get setup and create a Project with the Youtube API: `https://developers.google.com/youtube/v3/quickstart/python` Be sure to follow it carefully, as it won't work if you don't do this part right. Download your OATH file as `client_secrets.json` in your project folder. 10 | 6. Open `main.py` in a text editor and fill in credentials 11 | 7. Run `python3 main.py` and authenticate your account 12 | 8. Enjoy Your Automated NEWS Channel -------------------------------------------------------------------------------- /License.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Neelesh Pandey 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /UploadOnYoutube.py: -------------------------------------------------------------------------------- 1 | from Google import Create_Service 2 | from googleapiclient.http import MediaFileUpload 3 | 4 | CLIENT_SECRET_FILE = 'client_secrets.json' #API File Add Here(client Secret File) 5 | API_NAME = 'youtube' 6 | API_VERSION = 'v3' 7 | SCOPES = ['https://www.googleapis.com/auth/youtube.upload'] 8 | 9 | def uploadOnYoutube(description): #Video Uploading Function 10 | service = Create_Service(CLIENT_SECRET_FILE,API_NAME,API_VERSION,SCOPES) 11 | 12 | request_body={ 13 | 'snippet':{ 14 | 'categoryId':25, 15 | 'title':'Todays Top Tech Headlines | Latest Tech News', #Title 16 | 'description':description, #Description 17 | 'tags':['Tech News','News'] #Tags 18 | }, 19 | 'status':{ 20 | 'privacyStatus':'public', #Add Privacy Status ["public","private","unlisted"] 21 | 'selfDeclaredMadeForKids': False 22 | }, 23 | 'notifySubscribers': False 24 | } 25 | 26 | mediaFile = MediaFileUpload('.\output.mp4') #Selecting File(video) Which Is To Be Uploded 27 | 28 | response_upload = service.videos().insert( 29 | part='snippet,status', 30 | body=request_body, 31 | media_body=mediaFile 32 | ).execute() 33 | 34 | if __name__ == "__main__": 35 | uploadOnYoutube('') -------------------------------------------------------------------------------- /Google.py: -------------------------------------------------------------------------------- 1 | import pickle 2 | import os 3 | from google_auth_oauthlib.flow import InstalledAppFlow 4 | from googleapiclient.discovery import build 5 | from google.auth.transport.requests import Request 6 | 7 | 8 | def Create_Service(client_secret_file, api_name, api_version, *scopes): 9 | CLIENT_SECRET_FILE = client_secret_file 10 | API_SERVICE_NAME = api_name 11 | API_VERSION = api_version 12 | SCOPES = [scope for scope in scopes[0]] 13 | 14 | cred = None 15 | 16 | pickle_file = f'token_{API_SERVICE_NAME}_{API_VERSION}.pickle' 17 | 18 | 19 | if os.path.exists(pickle_file): 20 | with open(pickle_file, 'rb') as token: 21 | cred = pickle.load(token) 22 | 23 | if not cred or not cred.valid: 24 | if cred and cred.expired and cred.refresh_token: 25 | cred.refresh(Request()) 26 | else: 27 | flow = InstalledAppFlow.from_client_secrets_file(CLIENT_SECRET_FILE, SCOPES) 28 | cred = flow.run_local_server() 29 | 30 | with open(pickle_file, 'wb') as token: 31 | pickle.dump(cred, token) 32 | 33 | try: 34 | service = build(API_SERVICE_NAME, API_VERSION, credentials=cred) 35 | print('Service Created Successfully') 36 | return service 37 | except Exception as e: 38 | print('Unable to connect.') 39 | print(e) 40 | return None -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | from newsapi import NewsApiClient 2 | from MakeVideo import makeVideo 3 | from UploadOnYoutube import uploadOnYoutube 4 | from CleanUp import cleanUp 5 | 6 | API_KEY = "" #Add NEWS API Here 7 | 8 | DOWNLOAD_IMAGES = './images/' #Add path to download images 9 | GEN_AUDIO = './audio/' #Add path to save generated audio 10 | INTRO_VIDEO = './intro.mp4' #Add path of intro video 11 | OUTRO_VIDEO = '' #Add path of outro video 12 | 13 | 14 | 15 | #Step 1: Getting Top Headlines 16 | 17 | print("Step 1: Getting Top Headlines") 18 | 19 | try: 20 | newsapi = NewsApiClient(api_key= API_KEY) 21 | all_articles = newsapi.get_top_headlines(category = 'technology', 22 | country = 'us', 23 | language='en', 24 | ) 25 | except Exception as e: 26 | print("There is some problem with API") 27 | print("The ERROR is",e,sep="\n") 28 | 29 | print("Step 1 Completed") 30 | 31 | 32 | 33 | 34 | #Step 2: Making a Video 35 | 36 | print("Step 2: Making a Video") 37 | 38 | description = makeVideo(articles = all_articles['articles'], 39 | imgpath = DOWNLOAD_IMAGES, 40 | audpath = GEN_AUDIO, 41 | intro = INTRO_VIDEO, 42 | outro = OUTRO_VIDEO 43 | ) 44 | 45 | print("Step 2 Completed") 46 | 47 | 48 | 49 | #Step 3: Uploading Video on YouTube 50 | 51 | print("Step 3: Uploading Video on YouTube") 52 | 53 | uploadOnYoutube(description) 54 | 55 | print("Step 3 Completed") 56 | 57 | 58 | 59 | #Step 4: Clean Up 60 | 61 | print("Step 4: Clean Up") 62 | 63 | cleanUp(imgfolder = DOWNLOAD_IMAGES, 64 | audfolder = GEN_AUDIO 65 | ) 66 | 67 | print("Step 4 Completed") 68 | 69 | print("MISSION ACCOMPLISHED") 70 | -------------------------------------------------------------------------------- /MakeVideo.py: -------------------------------------------------------------------------------- 1 | import urllib.request 2 | from gtts import gTTS 3 | from mutagen.mp3 import MP3 4 | from moviepy.editor import * 5 | from PIL import Image 6 | 7 | def getContextImages(article,c,imgpath): 8 | '''Converts News API Image URL to a Image(.png)''' 9 | urllib.request.urlretrieve(article['urlToImage'],imgpath+str(c)+".png") #URL to Image Conversion 10 | image = Image.open(imgpath+str(c)+".png") 11 | new_image = image.resize((1920, 1080)) #Resizing the Image 12 | new_image.save(imgpath+str(c)+".png") 13 | 14 | def generateAudio(article,c,audpath): 15 | '''Converts Text NEWS to audio(mp3)''' 16 | con = str(c+1)+article['title']+article["description"] #Getting Content that needs to be converted to audio 17 | tts = gTTS(con,lang="en") #Converting to audio 18 | tts.save(audpath+str(c)+'.mp3') #Saving the audio 19 | audio = MP3(audpath+str(c)+".mp3") 20 | return int(audio.info.length) #returning duration of audio 21 | 22 | def generateVideo(duration,c,imgpath,audpath): 23 | '''generating video using images and audio''' 24 | clip = ImageSequenceClip([imgpath+str(c)+'.png'], durations=[duration]) 25 | audioclip = AudioFileClip(audpath+str(c)+".mp3") 26 | videoclip = clip.set_audio(audioclip) 27 | return videoclip 28 | 29 | def makeVideo(articles,imgpath,audpath,intro,outro): 30 | '''This Function Generates a Output Video''' 31 | if not os.path.exists(imgpath): #Making Directories to save files 32 | os.makedirs(imgpath) 33 | if not os.path.exists(audpath): 34 | os.makedirs(audpath) 35 | 36 | c = 0 37 | description = '' 38 | clips = [] 39 | if intro != '': #Adding intro video 40 | clips.append(VideoFileClip(intro)) 41 | for article in articles: 42 | try: 43 | if c > 10: #Number of Headlines(Change it according to your need) 44 | break 45 | 46 | getContextImages(article,c,imgpath) 47 | 48 | duration = generateAudio(article,c,audpath) 49 | 50 | clips.append(generateVideo(duration,c,imgpath,audpath)) 51 | 52 | desc = [['Source : ',article['source']['name']], 53 | ['Author : ',article['author']], 54 | ['Url : ',article['url']]] 55 | for des in desc: 56 | if des[1] is not None: 57 | description += des[0]+des[1]+'\n' 58 | description += '\n' 59 | 60 | c += 1 61 | 62 | print("Clip",c,": Successfully Created") 63 | 64 | except Exception as e: 65 | print("Skipped one, there is a Problem") 66 | print("The Error Is",e,sep="\n") 67 | 68 | 69 | if outro != '': #Adding outro video 70 | clips.append(VideoFileClip(outro)) 71 | outputVideo = concatenate_videoclips(clips,method='compose') 72 | outputVideo.to_videofile("output.mp4",threads=8, remove_temp=True) 73 | 74 | return description 75 | 76 | if __name__ == "__main__": 77 | description = makeVideo(articles = '', 78 | imgpath = '', 79 | audpath = '', 80 | intro = '', 81 | outro = '' 82 | ) 83 | --------------------------------------------------------------------------------