@@ -19,10 +19,9 @@ import axios from "axios";
1919import pdfToText from "react-pdftotext" ;
2020import OpenAI from "openai" ;
2121import { useAuth } from "../contexts/AuthContext" ;
22+ import { useApiKeys } from "../contexts/ApiKeyContext" ;
2223
23- interface DocumentToMediaProps {
24- apiKey : string ;
25- }
24+ interface DocumentToMediaProps { }
2625
2726interface Voice {
2827 voice_id : string ;
@@ -31,7 +30,7 @@ interface Voice {
3130 preview_url ?: string ;
3231}
3332
34- const DocumentToMedia : React . FC < DocumentToMediaProps > = ( { apiKey } ) => {
33+ const DocumentToMedia : React . FC < DocumentToMediaProps > = ( ) => {
3534 const [ pdfFile , setPdfFile ] = useState < File | null > ( null ) ;
3635 const [ extractedText , setExtractedText ] = useState < string > ( "" ) ;
3736 const [ customPrompt , setCustomPrompt ] = useState < string > ( "" ) ;
@@ -54,7 +53,6 @@ const DocumentToMedia: React.FC<DocumentToMediaProps> = ({ apiKey }) => {
5453 const [ stability , setStability ] = useState ( 0.5 ) ;
5554 const [ similarityBoost , setSimilarityBoost ] = useState ( 0.75 ) ;
5655 const [ isLoadingVoices , setIsLoadingVoices ] = useState ( false ) ;
57- const [ openaiApiKey , setOpenaiApiKey ] = useState < string > ( "" ) ;
5856 const [ useSimpleProcessing , setUseSimpleProcessing ] = useState < boolean > ( true ) ;
5957
6058 const fileInputRef = useRef < HTMLInputElement > ( null ) ;
@@ -63,20 +61,24 @@ const DocumentToMedia: React.FC<DocumentToMediaProps> = ({ apiKey }) => {
6361 const canvasRef = useRef < HTMLCanvasElement | null > ( null ) ;
6462
6563 const { updateUserStats } = useAuth ( ) ;
64+ const { getElevenLabsKey, getOpenAiKey } = useApiKeys ( ) ;
6665
6766 // Fetch ElevenLabs voices on component mount
6867 useEffect ( ( ) => {
69- if ( apiKey ) {
68+ const elevenLabsKey = getElevenLabsKey ( ) ;
69+ if ( elevenLabsKey ) {
7070 fetchVoices ( ) ;
7171 }
72- } , [ apiKey ] ) ;
72+ } , [ getElevenLabsKey ] ) ;
7373
7474 const fetchVoices = async ( ) => {
7575 setIsLoadingVoices ( true ) ;
76+ const elevenLabsKey = getElevenLabsKey ( ) ;
77+
7678 try {
7779 const response = await axios . get ( "https://api.elevenlabs.io/v1/voices" , {
7880 headers : {
79- "xi-api-key" : apiKey ,
81+ "xi-api-key" : elevenLabsKey ,
8082 } ,
8183 } ) ;
8284
@@ -239,10 +241,10 @@ const DocumentToMedia: React.FC<DocumentToMediaProps> = ({ apiKey }) => {
239241 try {
240242 let result = extractedText ;
241243
242- if ( ! useSimpleProcessing && openaiApiKey ) {
244+ if ( ! useSimpleProcessing && getOpenAiKey ( ) ) {
243245 try {
244246 const openai = new OpenAI ( {
245- apiKey : openaiApiKey ,
247+ apiKey : getOpenAiKey ( ) ,
246248 dangerouslyAllowBrowser : true ,
247249 } ) ;
248250
@@ -301,7 +303,7 @@ const DocumentToMedia: React.FC<DocumentToMediaProps> = ({ apiKey }) => {
301303 } ;
302304
303305 const generateAudio = async ( ) => {
304- if ( ! processedText || ! apiKey ) return ;
306+ if ( ! processedText || ! getElevenLabsKey ( ) ) return ;
305307
306308 setIsGeneratingAudio ( true ) ;
307309 setError ( null ) ;
@@ -321,7 +323,7 @@ const DocumentToMedia: React.FC<DocumentToMediaProps> = ({ apiKey }) => {
321323 headers : {
322324 Accept : "audio/mpeg" ,
323325 "Content-Type" : "application/json" ,
324- "xi-api-key" : apiKey ,
326+ "xi-api-key" : getElevenLabsKey ( ) ,
325327 } ,
326328 responseType : "blob" ,
327329 }
@@ -729,21 +731,23 @@ const DocumentToMedia: React.FC<DocumentToMediaProps> = ({ apiKey }) => {
729731 </ div >
730732
731733 { ! useSimpleProcessing && (
732- < div className = "space-y-2" >
733- < label className = "block text-sm font-medium text-gray-300" >
734- OpenAI API Key (for AI processing)
735- </ label >
736- < input
737- type = "password"
738- value = { openaiApiKey }
739- onChange = { ( e ) => setOpenaiApiKey ( e . target . value ) }
740- placeholder = "sk-..."
741- className = "w-full px-4 py-3 bg-gray-600 border border-gray-500 rounded-lg text-white placeholder-gray-400 focus:outline-none focus:ring-2 focus:ring-cyan-500 focus:border-transparent transition-all duration-200"
742- />
743- < p className = "text-xs text-gray-500" >
744- Required for advanced AI features like translation to Hindi,
745- content summarization, etc.
746- </ p >
734+ < div className = "mb-6" >
735+ < div className = "bg-cyan-900/20 border border-cyan-500/30 rounded-lg p-4" >
736+ < p className = "text-cyan-400 text-sm font-medium mb-2" >
737+ 🔑 AI Processing Enabled
738+ </ p >
739+ < p className = "text-gray-400 text-xs" >
740+ { getOpenAiKey ( )
741+ ? "Using your OpenAI API key for enhanced AI features like translation, summarization, and content enhancement."
742+ : "OpenAI API key not found. Please add your OpenAI API key in Settings to enable AI processing features." }
743+ </ p >
744+ { ! getOpenAiKey ( ) && (
745+ < p className = "text-yellow-400 text-xs mt-2" >
746+ ⚠️ Without an OpenAI API key, only simple text processing
747+ will be available.
748+ </ p >
749+ ) }
750+ </ div >
747751 </ div >
748752 ) }
749753 </ div >
@@ -766,7 +770,7 @@ const DocumentToMedia: React.FC<DocumentToMediaProps> = ({ apiKey }) => {
766770 disabled = {
767771 isProcessing ||
768772 ! customPrompt . trim ( ) ||
769- ( ! useSimpleProcessing && ! openaiApiKey . trim ( ) )
773+ ( ! useSimpleProcessing && ! getOpenAiKey ( ) )
770774 }
771775 className = "w-full bg-cyan-600 hover:bg-cyan-700 text-white font-medium px-6 py-3 rounded-lg transition-all duration-200 flex items-center justify-center disabled:opacity-50 disabled:cursor-not-allowed shadow-lg hover:shadow-xl"
772776 >
@@ -865,10 +869,9 @@ const DocumentToMedia: React.FC<DocumentToMediaProps> = ({ apiKey }) => {
865869
866870 { processedText && (
867871 < div className = "bg-gray-800 rounded-xl p-4 lg:p-6 border border-gray-700" >
868- < div className = "flex flex-col sm:flex-row sm:items-center justify-between mb-2 space-y-2 sm:space-y-0" >
869- < h3 className = "text-lg lg:text-xl font-bold text-white flex items-center" >
870- < Mic className = "mr-2 h-5 w-5 text-green-400" />
871- Professional Audio Generation
872+ < div className = "flex items-center justify-between" >
873+ < h3 className = "text-lg font-semibold text-white" >
874+ Audio Generation
872875 </ h3 >
873876 < div className = "flex items-center space-x-2" >
874877 < button
@@ -894,6 +897,15 @@ const DocumentToMedia: React.FC<DocumentToMediaProps> = ({ apiKey }) => {
894897 Generate high-quality, natural-sounding audio narration from your
895898 processed content
896899 </ p >
900+ { audioUrl && (
901+ < audio
902+ ref = { audioRef }
903+ src = { audioUrl }
904+ onEnded = { ( ) => setIsPlaying ( false ) }
905+ onPause = { ( ) => setIsPlaying ( false ) }
906+ onPlay = { ( ) => setIsPlaying ( true ) }
907+ />
908+ ) }
897909
898910 < div className = "mb-4 space-y-2" >
899911 < label className = "block text-sm font-medium text-gray-300" >
@@ -918,12 +930,12 @@ const DocumentToMedia: React.FC<DocumentToMediaProps> = ({ apiKey }) => {
918930 ) }
919931 </ select >
920932
921- { selectedVoice && (
933+ { /* { selectedVoice && (
922934 <div className="mt-2 p-2 bg-gray-700 rounded text-sm border border-gray-600">
923935 <span className="text-gray-400">Selected Voice ID: </span>
924936 <span className="text-cyan-400 font-mono">{selectedVoice}</span>
925937 </div>
926- ) }
938+ )} */ }
927939 </ div >
928940
929941 { showSettings && (
@@ -966,7 +978,7 @@ const DocumentToMedia: React.FC<DocumentToMediaProps> = ({ apiKey }) => {
966978 < button
967979 onClick = { generateAudio }
968980 disabled = { isGeneratingAudio || ! processedText . trim ( ) }
969- className = "w-full bg-green -600 hover:bg-green -700 text-white font-medium px-6 py-3 rounded-lg transition-all duration-200 flex items-center justify-center disabled:opacity-50 disabled:cursor-not-allowed shadow-lg hover:shadow-xl mb-4"
981+ className = "w-full bg-cyan -600 hover:bg-cyan -700 text-white font-medium px-6 py-3 rounded-lg transition-all duration-200 flex items-center justify-center disabled:opacity-50 disabled:cursor-not-allowed shadow-lg hover:shadow-xl mb-4"
970982 >
971983 { isGeneratingAudio ? (
972984 < >
@@ -998,7 +1010,7 @@ const DocumentToMedia: React.FC<DocumentToMediaProps> = ({ apiKey }) => {
9981010
9991011 < button
10001012 onClick = { downloadAudio }
1001- className = "flex items-center space-x-2 bg-green -600 text-white px-6 py-3 rounded-lg hover:bg-green -700 transition-colors w-full sm:w-auto justify-center"
1013+ className = "flex items-center space-x-2 bg-cyan -600 text-white px-6 py-3 rounded-lg hover:bg-cyan -700 transition-colors w-full sm:w-auto justify-center"
10021014 >
10031015 < Download className = "h-5 w-5" />
10041016 < span > Download Audio</ span >
@@ -1068,7 +1080,7 @@ const DocumentToMedia: React.FC<DocumentToMediaProps> = ({ apiKey }) => {
10681080 < div className = "flex justify-center" >
10691081 < button
10701082 onClick = { downloadVideo }
1071- className = "flex items-center space-x-2 bg-green -600 text-white px-6 py-3 rounded-lg hover:bg-green -700 transition-colors"
1083+ className = "flex items-center space-x-2 bg-cyan -600 text-white px-6 py-3 rounded-lg hover:bg-cyan -700 transition-colors"
10721084 >
10731085 < Download className = "h-5 w-5" />
10741086 < span > Download Video</ span >
0 commit comments