createVideo.ts 3.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. import UploadCommandBase from '../../base/UploadCommandBase'
  2. import { getInputJson } from '../../helpers/InputOutput'
  3. import { asValidatedMetadata, metadataToBytes } from '../../helpers/serialization'
  4. import { VideoInputParameters, VideoFileMetadata } from '../../Types'
  5. import { CreateInterface } from '@joystream/types'
  6. import { flags } from '@oclif/command'
  7. import { VideoCreationParameters } from '@joystream/types/content'
  8. import { IVideoMetadata, VideoMetadata } from '@joystream/metadata-protobuf'
  9. import { integrateMeta } from '@joystream/metadata-protobuf/utils'
  10. import chalk from 'chalk'
  11. export default class CreateVideoCommand extends UploadCommandBase {
  12. static description = 'Create video under specific channel inside content directory.'
  13. static flags = {
  14. input: flags.string({
  15. char: 'i',
  16. required: true,
  17. description: `Path to JSON file to use as input`,
  18. }),
  19. channelId: flags.integer({
  20. char: 'c',
  21. required: true,
  22. description: 'ID of the Channel',
  23. }),
  24. }
  25. setVideoMetadataDefaults(metadata: IVideoMetadata, videoFileMetadata: VideoFileMetadata): void {
  26. const videoMetaToIntegrate = {
  27. duration: videoFileMetadata.duration,
  28. mediaPixelWidth: videoFileMetadata.width,
  29. mediaPixelHeight: videoFileMetadata.height,
  30. }
  31. const mediaTypeMetaToIntegrate = {
  32. codecName: videoFileMetadata.codecName,
  33. container: videoFileMetadata.container,
  34. mimeMediaType: videoFileMetadata.mimeType,
  35. }
  36. integrateMeta(metadata, videoMetaToIntegrate, ['duration', 'mediaPixelWidth', 'mediaPixelHeight'])
  37. integrateMeta(metadata.mediaType || {}, mediaTypeMetaToIntegrate, ['codecName', 'container', 'mimeMediaType'])
  38. }
  39. async run() {
  40. const { input, channelId } = this.parse(CreateVideoCommand).flags
  41. // Get context
  42. const channel = await this.getApi().channelById(channelId)
  43. const [actor, address] = await this.getChannelOwnerActor(channel)
  44. // Get input from file
  45. const videoCreationParametersInput = await getInputJson<VideoInputParameters>(input)
  46. const meta = asValidatedMetadata(VideoMetadata, videoCreationParametersInput)
  47. // Assets
  48. const { videoPath, thumbnailPhotoPath } = videoCreationParametersInput
  49. const assetsPaths = [videoPath, thumbnailPhotoPath].filter((a) => a !== undefined) as string[]
  50. const inputAssets = await this.prepareInputAssets(assetsPaths, input)
  51. const assets = inputAssets.map(({ parameters }) => ({ Upload: parameters }))
  52. // Set assets indexes in the metadata
  53. const [videoIndex, thumbnailPhotoIndex] = this.assetsIndexes([videoPath, thumbnailPhotoPath], assetsPaths)
  54. meta.video = videoIndex
  55. meta.thumbnailPhoto = thumbnailPhotoIndex
  56. // Try to get video file metadata
  57. if (videoIndex !== undefined) {
  58. const videoFileMetadata = await this.getVideoFileMetadata(inputAssets[videoIndex].path)
  59. this.log('Video media file parameters established:', videoFileMetadata)
  60. this.setVideoMetadataDefaults(meta, videoFileMetadata)
  61. }
  62. // Create final extrinsic params and send the extrinsic
  63. const videoCreationParameters: CreateInterface<VideoCreationParameters> = {
  64. assets,
  65. meta: metadataToBytes(VideoMetadata, meta),
  66. }
  67. this.jsonPrettyPrint(JSON.stringify({ assets, metadata: meta }))
  68. await this.requireConfirmation('Do you confirm the provided input?', true)
  69. const result = await this.sendAndFollowNamedTx(await this.getDecodedPair(address), 'content', 'createVideo', [
  70. actor,
  71. channelId,
  72. videoCreationParameters,
  73. ])
  74. if (result) {
  75. const event = this.findEvent(result, 'content', 'VideoCreated')
  76. const videoId = event?.data[2]
  77. this.log(chalk.green(`Video with id ${chalk.cyanBright(videoId?.toString())} successfully created!`))
  78. }
  79. // Upload assets
  80. await this.uploadAssets(inputAssets, input)
  81. }
  82. }