ニジカ投稿局 https://tv.nizika.tv
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

96 lines
2.1 KiB

  1. import { AllowNull, BelongsTo, Column, CreatedAt, ForeignKey, Table, UpdatedAt } from 'sequelize-typescript'
  2. import { MVideo, MVideoChapter } from '@server/types/models/index.js'
  3. import { VideoChapter, VideoChapterObject } from '@peertube/peertube-models'
  4. import { VideoModel } from './video.js'
  5. import { Transaction } from 'sequelize'
  6. import { getSort } from '../shared/sort.js'
  7. import { SequelizeModel } from '../shared/sequelize-type.js'
  8. @Table({
  9. tableName: 'videoChapter',
  10. indexes: [
  11. {
  12. fields: [ 'videoId', 'timecode' ],
  13. unique: true
  14. }
  15. ]
  16. })
  17. export class VideoChapterModel extends SequelizeModel<VideoChapterModel> {
  18. @AllowNull(false)
  19. @Column
  20. timecode: number
  21. @AllowNull(false)
  22. @Column
  23. title: string
  24. @ForeignKey(() => VideoModel)
  25. @Column
  26. videoId: number
  27. @BelongsTo(() => VideoModel, {
  28. foreignKey: {
  29. allowNull: false
  30. },
  31. onDelete: 'CASCADE'
  32. })
  33. Video: Awaited<VideoModel>
  34. @CreatedAt
  35. createdAt: Date
  36. @UpdatedAt
  37. updatedAt: Date
  38. static deleteChapters (videoId: number, transaction: Transaction) {
  39. const query = {
  40. where: {
  41. videoId
  42. },
  43. transaction
  44. }
  45. return VideoChapterModel.destroy(query)
  46. }
  47. static listChaptersOfVideo (videoId: number, transaction?: Transaction) {
  48. const query = {
  49. where: {
  50. videoId
  51. },
  52. order: getSort('timecode'),
  53. transaction
  54. }
  55. return VideoChapterModel.findAll<MVideoChapter>(query)
  56. }
  57. static hasVideoChapters (videoId: number, transaction: Transaction) {
  58. return VideoChapterModel.findOne({
  59. where: { videoId },
  60. transaction
  61. }).then(c => !!c)
  62. }
  63. toActivityPubJSON (this: MVideoChapter, options: {
  64. video: MVideo
  65. nextChapter: MVideoChapter
  66. }): VideoChapterObject {
  67. return {
  68. name: this.title,
  69. startOffset: this.timecode,
  70. endOffset: options.nextChapter
  71. ? options.nextChapter.timecode
  72. : options.video.duration
  73. }
  74. }
  75. toFormattedJSON (this: MVideoChapter): VideoChapter {
  76. return {
  77. timecode: this.timecode,
  78. title: this.title
  79. }
  80. }
  81. }