import gradio as gr import numpy as np import cv2 import librosa import tempfile import wave import os import speech_recognition as sr import pickle import json from tensorflow.keras.models import load_model from tensorflow.keras.preprocessing.text import tokenizer_from_json from tensorflow.keras.preprocessing.sequence import pad_sequences import nltk from collections import Counter from transformers import LlamaTokenizer, LlamaForCausalLM # Initialize necessary models and tools # Load the tokenizer and model for text-based emotion prediction with open('tokenizer.json') as json_file: tokenizer_json = json.load(json_file) tokenizer = tokenizer_from_json(tokenizer_json) text_model = load_model('model_for_text_emotion_updated(1).keras') # Load the audio emotion model and scaler with open('encoder.pkl', 'rb') as file: encoder = pickle.load(file) with open('scaler.pkl', 'rb') as file: scaler = pickle.load(file) audio_model = load_model('my_model.h5') # Load the LLaMA model for question answering llama_tokenizer = LlamaTokenizer.from_pretrained('huggingface/llama-7b') llama_model = LlamaForCausalLM.from_pretrained('huggingface/llama-7b') # Initialize NLTK tools nltk.download('punkt') nltk.download('wordnet') nltk.download('stopwords') lemmatizer = nltk.WordNetLemmatizer() stop_words = set(nltk.corpus.stopwords.words('english')) # Preprocess text for emotion prediction def preprocess_text(text): tokens = nltk.word_tokenize(text.lower()) tokens = [word for word in tokens if word.isalnum() and word not in stop_words] lemmatized_tokens = [lemmatizer.lemmatize(word) for word in tokens] return ' '.join(lemmatized_tokens) # Extract audio features and predict emotion def extract_audio_features(data, sample_rate): result = np.array([]) zcr = np.mean(librosa.feature.zero_crossing_rate(y=data).T, axis=0) result = np.hstack((result, zcr)) mfcc = np.mean(librosa.feature.mfcc(y=data, sr=sample_rate).T, axis=0) result = np.hstack((result, mfcc)) return result def predict_emotion_from_audio(audio_data): sample_rate, data = audio_data features = extract_audio_features(data, sample_rate) features = np.expand_dims(features, axis=0) scaled_features = scaler.transform(features) prediction = audio_model.predict(scaled_features) emotion_index = np.argmax(prediction) emotion_array = np.zeros((1, len(encoder.categories_[0]))) emotion_array[0, emotion_index] = 1 emotion_label = encoder.inverse_transform(emotion_array)[0] return emotion_label # Extract text from audio (speech recognition) def extract_text_from_audio(audio_path): recognizer = sr.Recognizer() with sr.AudioFile(audio_path) as source: audio_data = recognizer.record(source) text = recognizer.recognize_google(audio_data) return text # Use LLaMA to answer questions based on the text def ask_llama(question, context): inputs = llama_tokenizer(question, context, return_tensors="pt") outputs = llama_model.generate(inputs['input_ids'], max_length=150) answer = llama_tokenizer.decode(outputs[0], skip_special_tokens=True) return answer # Process the video and extract text, emotion, and context for LLaMA def process_video(video_path): # Extract audio from the video video = mp.VideoFileClip(video_path) if video.audio is None: raise ValueError("No audio found in the video.") audio = video.audio with tempfile.NamedTemporaryFile(delete=False, suffix=".wav") as temp_audio_file: temp_audio_path = temp_audio_file.name audio.write_audiofile(temp_audio_path) # Extract text from the audio video_text = extract_text_from_audio(temp_audio_path) # Predict emotions from the text and audio preprocessed_text = preprocess_text(video_text) title_seq = tokenizer.texts_to_sequences([preprocessed_text]) padded_title_seq = pad_sequences(title_seq, maxlen=35, padding='post', truncating='post') text_emotion_prediction = text_model.predict(np.array(padded_title_seq)) text_emotion = ['anger', 'disgust', 'fear', 'joy', 'neutral', 'sadness', 'surprise'][np.argmax(text_emotion_prediction)] audio_data = audio.to_soundarray(fps=audio.fps) audio_emotion = predict_emotion_from_audio((audio.fps, audio_data)) # Answer user queries based on the video text context = video_text return context, text_emotion, audio_emotion # Define Gradio Interface def video_query_interface(video, question): context, text_emotion, audio_emotion = process_video(video) answer = ask_llama(question, context) return f"Text Emotion: {text_emotion}, Audio Emotion: {audio_emotion}\nAnswer: {answer}" iface = gr.Interface(fn=video_query_interface, inputs=[gr.Video(), gr.Textbox()], outputs="text", title="Video Emotion and Q&A", description="Upload a video and ask a question based on the audio content.") iface.launch()