#background #next.js
#фон #next.js
Вопрос:
Я хочу добавить фоновое видео в формате mp4, но NextJS показывает ошибку:
./public/video/ocean.mp4 1:0
Module parse failed: Unexpected character '' (1:0)
You may need an appropriate loader to handle this file type, currently
no loaders are configured to process this file. See
https://webpack.js.org/concepts#loaders
(Исходный код опущен для этого двоичного файла)
import React, {useEffect, useRef} from "react"
import Layout from "../components/webSite/layout";
import backgroundVideo from "../public/video/ocean.mp4"
const Home = () => {
const videoRef = useRef()
useEffect(() => {
setTimeout(()=>{
videoRef.current.play()
},5000)
}, []);
return <Layout title={"Home"}>
<video
ref={videoRef}
controls
width="250"
loop
muted
style={{
position: "relative",
width: "100%",
height: "15rem",
left: 0,
top: 0,
}}>
<source src={backgroundVideo} type="video/mp4"/>
</video>
</Layout>
}
export default Home
Ответ №1:
Все, что вы import
используете в React, на самом деле нуждается в загрузчике webpack, который понимает формат.
MP4 не является одним из этих форматов. Даже если бы это было так, импорт всего видеофайла был бы ужасно неэффективным 🙂
Решение: не импортируйте видеофайл, вместо этого ссылайтесь на него как на внешний файл, который браузер загружает по http, как и любой другой медиафайл. Все файлы, которые вы добавляете /public
, могут быть указаны под верхней папкой вашего веб-сайта:
<source src="/video/ocean.mp4" type="video/mp4"/>
Ответ №2:
В отличие от других ответов, не неэффективно импортировать .mp4
(используя правильный загрузчик), и для этого не требуется плагин, специфичный для NextJS.
Используя file-loader
, webpack предоставит вам URL-адрес в качестве импорта вашего .mp4
. Webpack просто копирует .mp4
в выходной каталог (не в пакете) и возвращает относительный URL-адрес для этого. Это будет запрошено обычно, когда вы используете его в <video>
элементе.
Чтобы использовать file-loader
for .mp4
s, вы можете добавить webpack()
обратный вызов к своему next.config.js
, как показано ниже.
export default {
webpack(config, { isServer }) {
const prefix = config.assetPrefix ?? config.basePath ?? '';
config.module.rules.push({
test: /.mp4$/,
use: [{
loader: 'file-loader',
options: {
publicPath: `${prefix}/_next/static/media/`,
outputPath: `${isServer ? '../' : ''}static/media/`,
name: '[name].[hash].[ext]',
},
}],
});
return config;
},
};
Затем просто импортируйте свой .mp4
и используйте его в <video>
элементе
import myvideo from './myvideo.mp4';
export default function MyVideo(){
return <video>
<source src={myvideo} type="video/mp4"/>
</video>;
}
Если вы используете Typescript, вы также захотите добавить объявление для расширений файлов, с которыми вы загружаете file-loader
. Это должно произойти через .d.ts
, Next.js рекомендует (прокрутите вниз, чтобы найти информационное окно с упоминанием об этом) создать additional.d.ts
, а затем добавить его в ваше свойство TS config include
.
// additional.d.ts
declare module '*.mp4' {
export default string;
}
Это в основном то, что ] next-videos
делает](https://github.com/jeremybarbet/next-videos/blob/master/index.js ) тоже под капотом.
Комментарии:
1. Есть ли какая-либо выгода в импорте файла с помощью загрузчика webpack по сравнению с прямой ссылкой на изображение из общей папки?
2. Если вы импортируете с помощью file-loader, это в основном делает то же самое, что и публичное размещение, просто это немного больше похоже на webpack. Учитывая, что загрузчик — это просто функция за кулисами, также может существовать специальный загрузчик для .mp4s, который выполняет оптимизацию (например, встроенный загрузчик изображений next выполняет srcset и другие оптимизации). Вы также могли бы довольно легко создать свой собственный загрузчик для оптимизации .mp4 и подключить его к чему-то вроде ffmpeg
Ответ №3:
Если первый ответ не сработает, попробуйте это:
Установите пакет под названием
next-videos
После установки перейдите на свойnext.config.js Файл в вашем проекте и сделайте это:
const withVideos = require('next-videos')
module.exports = withVideos()
Важно то, что после редактирования вашего файла конфигурации вам необходимо перезапустить сервер, если вы этого не сделаете, он тоже не будет работать.
В вашем файле вы должны использовать require()
в своем компоненте
Например, так:
export default () => (
<div>
<video src={(require('./video.mp4'))}/>
</div>
)
Вся информация используется из npm.js веб-сайт: