createVideo.ts 3.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. import UploadCommandBase from '../../base/UploadCommandBase'
  2. import { getInputJson } from '../../helpers/InputOutput'
  3. import { videoMetadataFromInput, 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 { MediaType, VideoMetadata } from '@joystream/content-metadata-protobuf'
  9. import { VideoInputSchema } from '../../json-schemas/ContentDirectory'
  10. export default class CreateVideoCommand extends UploadCommandBase {
  11. static description = 'Create video under specific channel inside content directory.'
  12. static flags = {
  13. input: flags.string({
  14. char: 'i',
  15. required: true,
  16. description: `Path to JSON file to use as input`,
  17. }),
  18. channelId: flags.integer({
  19. char: 'c',
  20. required: true,
  21. description: 'ID of the Channel',
  22. }),
  23. }
  24. setVideoMetadataDefaults(metadata: VideoMetadata, videoFileMetadata: VideoFileMetadata) {
  25. const metaObj = metadata.toObject()
  26. metadata.setDuration((metaObj.duration || videoFileMetadata.duration) as number)
  27. metadata.setMediaPixelWidth((metaObj.mediaPixelWidth || videoFileMetadata.width) as number)
  28. metadata.setMediaPixelHeight((metaObj.mediaPixelHeight || videoFileMetadata.height) as number)
  29. const fileMediaType = new MediaType()
  30. fileMediaType.setCodecName(videoFileMetadata.codecName as string)
  31. fileMediaType.setContainer(videoFileMetadata.container)
  32. fileMediaType.setMimeMediaType(videoFileMetadata.mimeType)
  33. metadata.setMediaType(metadata.getMediaType() || fileMediaType)
  34. }
  35. async run() {
  36. const { input, channelId } = this.parse(CreateVideoCommand).flags
  37. // Get context
  38. const account = await this.getRequiredSelectedAccount()
  39. const channel = await this.getApi().channelById(channelId)
  40. const actor = await this.getChannelOwnerActor(channel)
  41. await this.requestAccountDecoding(account)
  42. // Get input from file
  43. const videoCreationParametersInput = await getInputJson<VideoInputParameters>(input, VideoInputSchema)
  44. const meta = videoMetadataFromInput(videoCreationParametersInput)
  45. // Assets
  46. const { videoPath, thumbnailPhotoPath } = videoCreationParametersInput
  47. const assetsPaths = [videoPath, thumbnailPhotoPath].filter((a) => a !== undefined) as string[]
  48. const inputAssets = await this.prepareInputAssets(assetsPaths, input)
  49. const assets = inputAssets.map(({ parameters }) => ({ Upload: parameters }))
  50. // Set assets indexes in the metadata
  51. if (videoPath) {
  52. meta.setVideo(0)
  53. }
  54. if (thumbnailPhotoPath) {
  55. meta.setThumbnailPhoto(videoPath ? 1 : 0)
  56. }
  57. // Try to get video file metadata
  58. const videoFileMetadata = await this.getVideoFileMetadata(inputAssets[0].path)
  59. this.log('Video media file parameters established:', videoFileMetadata)
  60. this.setVideoMetadataDefaults(meta, videoFileMetadata)
  61. // Create final extrinsic params and send the extrinsic
  62. const videoCreationParameters: CreateInterface<VideoCreationParameters> = {
  63. assets,
  64. meta: metadataToBytes(meta),
  65. }
  66. this.jsonPrettyPrint(JSON.stringify({ assets, metadata: meta.toObject() }))
  67. await this.requireConfirmation('Do you confirm the provided input?', true)
  68. await this.sendAndFollowNamedTx(account, 'content', 'createVideo', [actor, channelId, videoCreationParameters])
  69. // Upload assets
  70. await this.uploadAssets(inputAssets, input)
  71. }
  72. }