)2hgddlmZddlmZddlmZddlmZmZddl m Z ddl m Z m Z mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZddlm Z m!Z!m"Z"m#Z#m$Z$ddl%m&Z&m'Z'm(Z(dd l)m*Z*dd l+Z+dd l,Z,dd l-m.Z.d Z/d Z0d#dZ1d#dZ2GddeZ3GddeZ4GddeZ5GddeZ6GddeZ7GddeZ8e5e6e7e8e3e4dZ9dddd d!d"dZ:y )$) annotations)cleandoc)Optional)IO ComfyNodeABC) VideoFromFile)LumaImageModelLumaVideoModelLumaVideoOutputResolutionLumaVideoModelOutputDurationLumaAspectRatio LumaStateLumaImageGenerationRequestLumaGenerationRequestLumaGenerationLumaCharacterRefLumaModifyImageRefLumaImageIdentity LumaReferenceLumaReferenceChainLumaImageReference LumaKeyframesLumaConceptChainLumaIOget_luma_concepts) ApiEndpoint HttpMethodSynchronousOperationPollingOperation EmptyRequest)upload_images_to_comfyapiprocess_image_responsevalidate_string) PromptServerN)BytesIOidcvt|dr,t|jdr|jjSdS)Nassetsimage)hasattrr)r*responses AD:\ComfyUI_windows_portable\ComfyUI\comfy_api_nodes\nodes_luma.pyimage_result_url_extractorr/0/$+Hh$?GHOO]dDe8?? okoocvt|dr,t|jdr|jjSdS)Nr)video)r+r)r3r,s r.video_result_url_extractorr43r0r1cteZdZdZej fZdZeexsdZ dZ dZ e dZ d d dZy) LumaReferenceNodezJ Holds an image and weight for use with Luma Generate Image node. )luma_refcreate_luma_referenceapi node/image/Lumactjddiftjddddddfdd tjfid S) NtooltipzImage to use as reference.?{Gz?zWeight of image reference.defaultminmaxstepr<r*weightr7requiredoptional)rIMAGEFLOATrLUMA_REFss r. INPUT_TYPESzLumaReferenceNode.INPUT_TYPESAs] HH!#?HH#&"" $#?  $$foo%78'  r1Nc ||j}n t}|jt|t |d|fS)NrE)cloneraddrround)selfr*rFr7s r.r9z'LumaReferenceNode.create_luma_referenceYs@  ~~'H)+H ]uVQ7GHI{r1N)r* torch.TensorrFfloatr7r)__name__ __module__ __qualname____doc__rrL RETURN_TYPES RETURN_NAMESr DESCRIPTIONFUNCTIONCATEGORY classmethodrOr9r1r.r6r66shOO%L L7=b)K&H$H  0RV!+0r?z:Weight of style image. Ignored if no style_image provided.r@)promptmodel aspect_ratioseedstyle_image_weightr<zkLuma Reference node connection to influence generation with input images; up to 4 images can be considered.z1Style reference image; only 1 image will be used.zYCharacter reference images; can be a batch of multiple, up to 4 images can be considered.)image_luma_ref style_imagecharacter_imageAUTH_TOKEN_COMFY_ORGAPI_KEY_COMFY_ORG UNIQUE_ID auth_token comfy_api_key unique_idrHrIhidden) rSTRINGr valuer ratio_16_9INTrKrrLrJ)rNrratios r.rOz#LumaImageGenerationNode.INPUT_TYPESs' II%)#%#D5CCN55;;NCE.=>oUU[[o>!?#=#=!FF#$ 126$F  HH#&"" $#_  '5$NOO!$Q#HH ST  HH!#~$&5!4(q= = D>s CCNc t|ddd} ||j|d| } d} ||j||| } d} |$t|d| }t t | } t td tjtt t|||| | | | }|j}ttd|jtjt t t"j$gt"j&gdt(| | }|j}t+j,|j.j0}t3|}|fS)NTstrip_whitespace min_lengthmax_refs auth_kwargs)rFr max_imagesr)images) identity0/proxy/luma/generations/imagepathmethod request_modelresponse_model)rrr image_ref style_ref character_refendpointrequestr/proxy/luma/generations/c|jSrVstatexs r.z2LumaImageGenerationNode.api_call..qwwr1 poll_endpointcompleted_statusesfailed_statusesstatus_extractorresult_url_extractornode_idr)r#_convert_luma_refs_convert_style_imager!rrrrrPOSTrrexecuteridGETr r completedfailedr/requestsgetr)r*r")rUrrrrrrrrrkwargs api_image_ref api_style_refr download_urls operation response_api response_poll img_responseimgs r.rwz LumaImageGenerationNode.api_callsw !D  % 334M  " 55$6F6M  &5A6M-+=AM) 4!8-  /)''+  "(1'8'8': $%/ /@A!~~*-  !* 3 34&--..!;  "))+ ||M$8$8$>$>? $\2v r1cg}d}|jD]:}t|jd|}|j|d|dz }||k\s:n|j ||S)Nrr)rr)refsr!r*appendcreate_api_model)rUr7rr luma_urls ref_countrefrs r.rz*LumaImageGenerationNode._convert_luma_refs'sr  ==C5 a[M   ]1- . NIH$!((y8(TTr1cXtt||}|j|d|S)NrE) first_refrr)rrr)rUrrFrrss r.rz,LumaImageGenerationNode._convert_style_image6s2##+fE &&uqk&RRr1NNNN)rrtrrtrrtrrXrrrrWrrWrrtrV)r7rrintrOptional[dict[str, str]])rrWrFrXrr)rYrZr[r\rrJr]rr_r`API_NODErarbrOrwrrrcr1r.rvrvsHH;L7=b)KHH$H> > N.2$((,III I " I+I"I&IIXcg U* U69 UH_ U `dS'S16SE\Sr1rvc|eZdZdZej fZeexsdZdZ dZ dZ e dZ d d dZy) LumaImageModifyNodezI Modifies images synchronously based on prompt and aspect ratio. r8rwTr:c tjftjddddftjddddd d ftDcgc]}|j c}ftj d d d dd dfdidddddScc}w)NTr8ryrzg?r>\(\?r?zLWeight of the image; the closer to 1.0, the less the image will be modified.r@rr|r}r~)r*r image_weightrrrrrrr)rrJrrKr rr)rNrs r.rOzLumaImageModifyNode.INPUT_TYPESJs((II%)#%#DHH#&"# $#q  !5CCN55;;NCEFF#$ 126$F  +@4!4(E' ' *DsA= Nc rt|d|}|d} ttdtjt t t ||t| tttd|z ddd   | } | j} ttd | jtjtt t j"gt j$gdt&||} | j} t)j*| j,j.} t1| }|fS)Nrrrrrr=rr>rQ)urlrF)rrmodify_image_refrrc|jSrVrrs r.rz.LumaImageModifyNode.api_call..rr1r)r!rrrrrrrrTrCrBrrrrr rrrr/rrr)r*r")rUrrr*rrrrr image_urlrrrrrs r.rwzLumaImageModifyNode.api_callus 2 aV "!$ ( 4!8-  /!3!%CL8H$4OQT0UWX*Y" (1'8'8': $%/ /@A!~~*-  !* 3 34&--..!;  "))+ ||M$8$8$>$>? $\2v r1rV) rrtrrtr*rWrrXrrt)rYrZr[r\rrJr]rr_r`rrarbrOrwrcr1r.rr?s~HH;L7=b)KHH$H( ( b444 4  44r1rceZdZdZej fZeexsdZdZ dZ dZ e dZ d d dZy) LumaTextToVideoGenerationNodezI Generates videos synchronously based on prompt and output_size. r8rwTrhc tjddddftDcgc]}|jc}ftDcgc]}|jc}dtj ift Dcgc]}|jc}dt jiftDcgc]}|jc}ftjddiftjddddd d fd d tjd difidddddScc}wcc}wcc}wcc}w)NTr8Prompt for the video generationrzrAFrr|r}r~)rrr resolutiondurationlooprrfr<MOptional Camera Concepts to dictate camera motion via the Luma Concepts node.rrrrr) rrr rr rr res_540pr BOOLEANrrro)rNrrrdurs r.rOz)LumaTextToVideoGenerationNode.INPUT_TYPESsJ II%)#%#D5CCN55;;NCE.=>oUU[[o>!?#=#=!9RR8Q*Z%%8QR!#<#E#E 4PP3OCcii3OPRJJ!5FF#$ 126$F  ;'R ((!#r"5!4(c6 6 D> S QsC9C>+D D Nc "t|dd|tjk7r|nd}|tjk7r|nd}tt dt j ttt|||||||r|jnd| } | j} | r-tjjd| j| tt d | jt j t"tt$j&gt$j(gd t*| t,| } | j} t/j0| j2j4}t7t9|j:fS) NFrr/proxy/luma/generationsr)rrrrrrconceptsrLuma video generation started: rc|jSrVrrs r.rz8LumaTextToVideoGenerationNode.api_call.."rr1rrrrrrestimated_durationr)r#r ray_1_6rrrrrrrrr$instancesend_progress_textrrrr rrrr4LUMA_T2V_AVERAGE_DURATIONrrr)r3rr%content)rUrrrrrrrrfrrrrr vid_responses r.rwz&LumaTextToVideoGenerationNode.api_calls` 1E$(>(>>8D#(N,B,B#BZ ( .!3-  *%)!=J779PT! $(1'8'8':   ! ! 4 47VWcWfWfVg5hjs t$%/ /@A!~~*-  !* 3 34&--..!;8 "))+ ||M$8$8$>$>? gl&:&:;<>>r1)NN)rrtrrtrrtrrtrrtrboolrfrrrt)rYrZr[r\rVIDEOr]rr_r`rrarbrOrwrcr1r.rrsHH;L7=b)KHH$H7 7 D+/:?:?:? :?  :?  :?:?(:?:?r1rceZdZdZej fZeexsdZdZ dZ dZ e dZ d d dZ d d d Zy)LumaImageToVideoGenerationNodezX Generates videos synchronously based on prompt, input images, and output_size. r8rwTrhc tjddddftDcgc]}|jc}ftDcgc]}|jc}dtj ift Dcgc]}|jc}ftjddiftjddddd d fd tjd d iftjd diftjd difddddddScc}wcc}wcc}w)NTr8rrzrAFrr|r}r~)rrrrrrr<zFirst frame of generated video.zLast frame of generated video.r) first_image last_imagerfrrrrr) rrr rr rr rrrJrro)rNrrrs r.rOz*LumaImageToVideoGenerationNode.INPUT_TYPES9sB II%)#%#D5CCN55;;NCE 9RR8Q*Z%%8QR!#<#E#E 4PP3OCcii3OPRJJ!5FF#$ 126$F  5$NHH AB  "xx)5U)VW((!#r" 5!4(g8 8 D S QsC0C5+C: Nc  j| | td|j||| } |tjk7r|nd}|tjk7r|nd}t t dt jttt||tj|||| | r| jnd| } | j}| r-tjj!d|j"| t%t d|j"t j&t(tt*j,gt*j.gd t0| t2| } | j}t5j6|j8j:}t=t?|j@fS) Nz=At least one of first_image and last_image requires an input.)rrr)rrrrrr keyframesrrrrc|jSrVrrs r.rz9LumaImageToVideoGenerationNode.api_call..rr1r)! Exception_convert_to_keyframesr rrrrrrrr rrrr$rrrrrr rrrr4LUMA_I2V_AVERAGE_DURATIONrrr)r3rr%r)rUrrrrrrrrrfrrr rrrrs r.rwz'LumaImageToVideoGenerationNode.api_callus  :#5O ..{JTZ.[ $(>(>>8D#(N,B,B#BZ ( .!3-  *,77%!#=J779PT # &(1'8'8':   ! ! 4 47VWcWfWfVg5hjs t$%/ /@A!~~*-  !* 3 34&--..!;8 "))+ ||M$8$8$>$>? gl&:&:;<>>r1c||yd}d}|t|d|}td|d}|t|d|}td|d}t||S)Nrrr*r)typer)frame0frame1)r!rr)rUrrrrrrs r.r z4LumaImageToVideoGenerationNode._convert_to_keyframess}  :#5  "5{M(W-:JKF  !5qkM(W-:JKFF6::r1r)rrtrrtrrtrrtrrrrWrrWrfrrrt)NNN)rrWrrWrr)rYrZr[r\rrr]rr_r`rrarbrOrwr rcr1r.rr.sHH;L7=b)KHH$H9 9 F%)#'*.@?@?@? @?  @?  @?"@?!@?(@?@?H%)#'/3 ;!;!;- ;r1r) LumaImageNoder LumaVideoNodeLumaImageToVideoNoder6rezLuma Text to ImagezLuma Image to ImagezLuma Text to VideozLuma Image to VideozLuma Referencez Luma Concepts)r-r); __future__rinspectrtypingrcomfy.comfy_types.node_typingrr comfy_api.input_impl.video_typesrcomfy_api_nodes.apis.luma_apir r r r r rrrrrrrrrrrrrrcomfy_api_nodes.apis.clientrrrrr comfy_api_nodes.apinode_utilsr!r"r#serverr$rtorchior%rr r/r4r6rervrrrNODE_CLASS_MAPPINGSNODE_DISPLAY_NAME_MAPPINGSrcr1r.r"s"::*   pp+ +\)|)XlSllS^j,jZ?L?D];\];F-.2:*( *0)1)' r1