원격을 사용하여 YouTube용 mp4 비디오 생성

12438 단어

요약



저는 귓속말을 사용하여 YouTube 동영상에서 대본을 추출하는 방법을 다루었습니다. 이 게시물에서는 원격에서 생성된 비디오를 사용하는 방법에 대해 설명합니다.

원격



먼저 생성된 원격 템플릿을 사용했고 원본 tts 템플릿에서 영감을 받았지만 Azure의 tts에 의존했습니다. 속삭임을 사용하여 대본이 포함된 json 파일을 생성한 다음 이를 사용하여 비디오를 생성할 수 있습니다.

ffmpeg를 사용하여 오디오를 mp3로 변환한 다음 속삭임 라이브러리를 사용하여 오디오를 전사할 수 있었습니다. 귓속말은 mp4 파일에서도 작동하며 ffmpeg를 설치해야 합니다.

import colorsJson from '../../public/uMzUL.json'

const {segments} = colorsJson;


먼저 json 파일에서 세그먼트를 추출합니다. 세그먼트는 성적표의 각 단어에 대한 타임스탬프입니다.

const renderSegment = () => {
  const secAdjustedFrame = frame / videoConfig.fps;
  const segmentIndex = segments.findIndex(segment => {
    return segment.start <= secAdjustedFrame && segment.end >= secAdjustedFrame;
  });
  const segment = segments[segmentIndex];
  if (!segment) {
    return <></>
  }
}


초기 코드는 현재 프레임을 잡은 다음 현재 프레임과 일치하는 세그먼트를 찾는 것입니다. 세그먼트가 없으면 빈 조각을 반환합니다. 비디오를 30fps로 렌더링하고 세그먼트가 초 단위이므로 프레임을 fps 단위로 조정해야 합니다.

const textDuration = segment.end - segment.start;
const words = segment.text.split(" ");

return (
  <div
    key={segment?.text}
  >
    {words.map((word, index) => {
      const wordStart = segment.start + (index * textDuration / words.length);
      return (
        <>
        <span 
          key={word}
          style={{
            color: titleColor,
            marginLeft: 10,
            marginRight: 10,
            opacity: (frame - (wordStart * videoConfig.fps)) / (videoConfig.fps * 0.5),
            transform: `scale(${spring({
              fps: videoConfig.fps,
              frame: frame - (wordStart * videoConfig.fps),
              config: {
                damping: 100,
                stiffness: 200,
                mass: 0.5,
              },
            })})`,
            display: 'inline-block',
          }}>
            {word}
          </span>
        </>
      )
    })}
  </div>
);


스프링을 사용하여 각 개별 단어에 애니메이션을 적용할 수 있도록 세그먼트를 단어로 분할합니다. 리모션에서 애니메이션을 사용할 때마다 깨끗한 애니메이션을 위한 참조 프레임이 있습니다. 이 경우 비디오의 프레임을 사용하고 단어의 시작 시간으로 조정합니다. 이를 통해 각 단어가 나타날 때 부드러운 애니메이션을 볼 수 있습니다.

불투명도와 배율을 사용하여 단어가 나타나는 대로 애니메이션을 적용할 수 있습니다. 불투명도는 프레임에서 단어의 시작 시간을 뺀 값을 fps로 나눈 값으로 설정됩니다. 이를 통해 각 단어가 나타날 때 부드러운 애니메이션을 볼 수 있습니다.

세그먼트 사용의 한 가지 단점은 단어가 화면에 잠시 남아 있다는 것입니다. 이는 세그먼트가 오디오 세그먼트를 기반으로 하기 때문입니다. 이것은 단어가 긴 세그먼트에 대해 나타나기 전에 오디오를 지연시킨다는 것을 의미합니다. 이것은 내가 앞으로 조사해야 할 것입니다. 감소하는 지수 함수가 이것을 처리하는 좋은 방법이라고 생각하십시오.

    const renderImage = () => {
        const images = ["img1.png", "img2.png"]
        const imageIndex = Math.floor(frame / (videoConfig.durationInFrames / images.length));
        const image = images[imageIndex];
        return (
            <Img src={staticFile(image)} style={{
                opacity: 0.25,
            }}/>
        );
    }

    return (
        <>
        {audioUrl ? <Audio src={staticFile(audioUrl)} /> : <></>}
        <AbsoluteFill>
            {renderImage()}
        </AbsoluteFill>
        <h1 style={title}>{titleText}</h1>
        <h1 style={mainText}>
            {renderSegment()}
            </h1>
        </>
    );


이미지를 생성하기 위해 dalle을 사용하여 비디오에 오버레이하는 데 사용할 수 있는 몇 개의 이미지를 생성할 수 있었습니다. 동영상이 중간 지점에 도달하면 새로운 이미지를 보여줍니다. 0.25의 불투명도가 사용되어 텍스트가 선명합니다. 또한 추출된 오디오(ffmpeg 사용)를 비디오에 추가했습니다.

동영상을 보려면 YouTube에서 볼 수 있습니다.

참조



  • 좋은 웹페이지 즐겨찾기