This guide will walk users through uploading and minting a video as an NFT using Livepeer, a decentralized video transcoding platform that has a streaming and video on demand API.
- Have node installed on your machine.
- Have a .mp4 video on your machine to upload.
- Have a metamask wallet and Metamask broswer extension.
- Have Polygon/Mumbai Testnet AND MATIC in your Metamask.
To learn how to add Mumbai Testnet to your wallet, follow these instructions.
- Get an API key for Livepeer here.
- Head to the directory where your video is stored - I'd suggest Desktop for ease.
- Run the following command in your terminal to install the Livepeer CLI:
npm install -g @livepeer/video-nft
(source code) - Run the following command in your terminal:
video-nft
- Enter your Livepeer API key from step 1
- Type in the name of the .mp4 you want to upload
- Name your NFT.
- Optionally customize the metadata for your video NFT by hitting
Y
when prompted.
- Once your video has successfully been uploaded you will get an object with fields, including your IPFS hash containing your metadata:
{
"videoFileCid": "Qmbo4CREdbLDTFEd3UFo4byTfes6YoN9CvBwSrMhnDqcpZ",
"nftMetadataCid": "QmXLQqt5zztHNj3ByvvopC7xbhNrdNPDutJQJvaoSBJ9eQ",
"videoFileUrl": "ipfs://Qmbo4CREdbLDTFEd3UFo4byTfes6YoN9CvBwSrMhnDqcpZ",
"videoFileGatewayUrl": "https://ipfs.livepeer.com/ipfs/Qmbo4CREdbLDTFEd3UFo4byTfes6YoN9CvBwSrMhnDqcpZ",
"nftMetadataUrl": "ipfs://QmXLQqt5zztHNj3ByvvopC7xbhNrdNPDutJQJvaoSBJ9eQ",
"nftMetadataGatewayUrl": "https://ipfs.livepeer.com/ipfs/QmXLQqt5zztHNj3ByvvopC7xbhNrdNPDutJQJvaoSBJ9eQ"
}
- The last line after a successful upload will give you a URL where you can pass in your custom ERC721 contract address or use the contract provided by Livepeer.
Prerequisite: Be sure to have your Metamask network configured to the Plolygon mainnet.
- After navigating to the URL provided, you can leave the contract field blank and default to Livepeer's contract. Hit "Mint NFT"
- You'll have to confirm the transaction and pay for the gas in Metamask.
- Done 🎉
- To view the metadata for this NFT, copy the IPFS hash provided to you in the terminal after uploadeding your video. You can take this hash and navigate to https://ipfs.io/ipfs/your-ipfs-hash-here
If you don't want to use Livepeer's contract to mint your NFT, you can create and deploy your own. For this workshop, we'll be using the Remix IDE
- Inside the remix broswer IDE, create a new file in the
contracts
folder. I'll name thismyNFT.sol
.
// contracts/4_ERC721.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "@openzeppelin/contracts/utils/Counters.sol";
contract VideoNFT is ERC721URIStorage {
using Counters for Counters.Counter;
Counters.Counter private _tokenIds;
constructor() ERC721("Video NFT", "VIDEO") {}
event Mint(
address indexed sender,
address indexed owner,
string tokenURI,
uint256 tokenId
);
function mint(address owner, string memory tokenURI)
public
returns (uint256)
{
require(
owner == msg.sender,
"Can only mint NFT for yourself on default contract"
);
_tokenIds.increment();
uint256 newItemId = _tokenIds.current();
_mint(owner, newItemId);
_setTokenURI(newItemId, tokenURI);
emit Mint(msg.sender, owner, tokenURI, newItemId);
return newItemId;
}
function uri(uint256 tokenId) public view returns (string memory) {
return tokenURI(tokenId);
}
}
If you want a step-by-step on what's happening in this code, read below 👇 If not, skip to step 4. | 3.
- Openzepplin provides solidity libraries which you can use to develop smart contracts easily and securely. We import the contract libraries for our project: ERC721 which is the parent.
ERC721URIStorage
gives us the methods necessary to associate an NFT with a URL, in this case an IPFS hash where we'll store the metadata.Counters
gives us some utility functions to safely assign a unique tokenID to each NFT we mint.
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol";
import "@openzeppelin/contracts/utils/Counters.sol";
- Define the constructor which takes in the name and symbol for your collection:
constructor() ERC721("Video NFT", "VIDEO") {}
- Define a Mint event to be emitted upon minting your NFT. We need to emit this event so your web3 client can get access to the tokenID after it has been minted.
event Mint(
address indexed sender,
address indexed owner,
string tokenURI,
uint256 tokenId
);
- Define a function
mint
that returns a tokenID. In this function, we make it so only the message signer can be the owner of the NFT. You can edit this for your contract if you want. In this function, we use the Counters utlity to increment the tokenID for each mint and set the tokenID for this NFT to be the current count. Then we call_mint
, a function inhereted from the ERC721 contract library we imported which actually associates the NFT with an owner via its ID. We call_setTokenURI
from the ERC721 library which sets the tokenURI. THen, we actually emit theMint
event we created eaelier. Lastly, we return the TokenID for this newly minted tokebn
function mint(address owner, string memory tokenURI)
public
returns (uint256)
{
require(
owner == msg.sender,
"Can only mint NFT for yourself on default contract"
);
_tokenIds.increment();
uint256 newItemId = _tokenIds.current();
_mint(owner, newItemId);
_setTokenURI(newItemId, tokenURI);
emit Mint(msg.sender, owner, tokenURI, newItemId);
return newItemId;
}
- We also define a function
uri
which takes in a tokenID and returns the tokenURI.
function uri(uint256 tokenId) public view returns (string memory) {
return tokenURI(tokenId);
}
- Then head over to the tab with the Ethereum icon. Here you'll compile and deploy your contract.