字幕
更新时间:2020-12-11
创建字幕轨道
- 创建字幕轨道,使用字幕相关功能,需要创建字幕轨并添加到媒体轨道中心,并创建一个字幕片段,配合字幕UI逻辑使用,详见智能小视频源码,涉及组件BDHKVlogSubtitlesView(字幕位置),BDMVSubtitleInputAccessoryView(字幕输入框),BDMVInputEventBottomBar(字幕确认框)
- 代码示例如下:
Plain Text
1 //创建字幕轨道
2 RMVPMediaVideoBlendItem *blendItem1 = [[RMVPMediaVideoBlendItem alloc] initWithBlendMode:RMVPMediaVideoBlendModeNormal];
3
4 subtitleTrack = [[RMVPMediaVisibleTrack alloc] initWithBlendItem:blendItem1];
5
6 subtitleTrack.trackId = kBDMVMediaVisibleSubtitleTrackId;
7
8 [self.videoTrack addVideoTrack:subtitleTrack];
9 //添加字幕片段
10 RMVPMediaTextSegment *subtitleSegment = [[RMVPMediaTextSegment alloc] init];
11
12 [subtitleTrack addSegment: subtitleSegment];
13
14
15 //配置字幕与预览实时显示
16 CGFloat videoWidth = self.previewer.previewConfig.width;
17
18 CGFloat videoHeight = self.previewer.previewConfig.height;
19
20 [self.videoTrack setupSubtitleStyleWithPreviewSize:CGSizeMake(videoWidth, videoHeight)];
添加多段字幕
- 添加多段字幕,请参考智能小视频编辑预览BBAShortVideoPreviewViewController.mm文件中的字幕逻辑,字幕默认显示2S
- 代码示例如下:
Plain Text
1 //获取字幕轨道中字幕片段
2 RMVPMediaTextSegment *textSegment = [self.videoTrack subtitleSegment];
3
4 //设置字幕内容,获取媒体轨道中心当前时间
5 CMTime currentTime = self.previewer.cursor.cursorTime;
6
7
8 //新增字幕
9 if (!currentItem) {
10
11 currentItem = [[RMVPMediaTextItem alloc] init];
12
13 currentItem.mainText = self.tmpMainTitle;
14
15 currentItem.subText = self.tmpSubTitle;
16
17 RMVPMediaTextItem *nextTextItem = nil;
18
19 NSArray *textAllItems = [textSegment textAllItem];
20
21 for (RMVPMediaTextItem *tmpItem in textAllItems) {
22
23 CMTimeRange timeRange = tmpItem.timeRange;
24 if (CMTimeCompare(timeRange.start, currentTime) > 0) {
25 nextTextItem = tmpItem;
26 break;
27 }
28 }
29
30 CGFloat newSubtitleDuration = [BDMVEditSubtitleSettings sharedInstance].addSubtitleDuration;
31
32 if (newSubtitleDuration <= 0) newSubtitleDuration = 2;
33
34 if (nextTextItem) {
35
36 CMTime eventualDuration;
37
38 CMTime nextItemStartTime = nextTextItem.timeRange.start;
39
40 CMTime gapTime = CMTimeSubtract(nextItemStartTime, currentTime);
41
42 if (CMTimeCompare(gapTime, CMTimeMake(newSubtitleDuration, 1)) >= 0) {
43 eventualDuration = CMTimeMake(newSubtitleDuration, 1);
44 } else {
45 eventualDuration = gapTime;
46 }
47
48 currentItem.timeRange = CMTimeRangeMake(currentTime, eventualDuration);
49
50 NSInteger index = [textSegment textIndexAtRefTime:nextItemStartTime];
51 //插入字幕到指定位置
52 [textSegment insertTextAtIndex:index item:currentItem];
53
54 [self.subtitleEditManager.seekBarAera insertSubtitleAtIndex:index];
55
56 } else {
57
58 CMTime eventualDuration;
59
60 CMTime mediaDuration = self.tracksCenter.userTrack.trackDuration;
61
62 CMTime remainingDuration = CMTimeSubtract(mediaDuration, currentTime);
63
64 if (CMTimeCompare(remainingDuration, CMTimeMake(newSubtitleDuration, 1)) >= 0) {
65
66 eventualDuration = CMTimeMake(newSubtitleDuration, 1);
67
68 } else {
69
70 eventualDuration = remainingDuration;
71
72 }
73
74 currentItem.timeRange = CMTimeRangeMake(currentTime, eventualDuration);
75 //追加字幕
76 [textSegment addTextWithItem:currentItem];
77
78 [self.subtitleEditManager.seekBarAera addSubtitle];
79
80 }
81
82 NSInteger index = [textSegment textIndexAtRefTime:self.previewer.cursor.cursorTime];
83 //更新字幕显示位置,详见[3.3.4 设置字幕画面位置]
84 [self updateSubtitleDisplayAndRealSubtitlePositonWithTransition:SubtitleInitTranslation itemIndex:index];
85
86 } else { // 编辑字幕
87
88 currentItem.mainText = self.tmpMainTitle;
89
90 currentItem.subText = self.tmpSubTitle;
91
92 NSInteger index = [textSegment textIndexAtRefTime:currentTime];
93
94 [self.subtitleEditManager.seekBarAera editSubtitleAtIndex:index];
95 }
设置字幕画面位置
- 设置字幕画面位置,可以调整字幕轨道上某个字幕的显示位置
- 代码示例如下:
Plain Text
1 //设置字幕显示位置
2 currentFrame = self.displaySubtitleTextView.frame;//displayView的位置已经更新
3
4 CGSize scale = [self currentVideoScale];
5
6 BDMVPreviewTransform transform = self.subtitlePreviewTransform;
7
8 CGFloat left = (CGRectGetMinX(currentFrame) - CGRectGetMinX(availabelRect) + Subtitle_InputView_OffsetX) / transform.scale;
9
10 left += [self currentVideoInvisibleHorizontalPadding];
11
12 CGFloat bottom = (CGRectGetMaxY(availabelRect) - CGRectGetMaxY(currentFrame) + Subtitle_InputView_OffsetX) / transform.scale;
13
14 CGFloat right = (CGRectGetMaxX(availabelRect) - CGRectGetMaxX(currentFrame) + Subtitle_InputView_OffsetX) / transform.scale;
15
16 right += [self currentVideoInvisibleHorizontalPadding];
17
18 RMVPMediaTextSegment *currentSegment = [self.tracksCenter subtitleSegment];
19
20 NSDictionary *attributes = @{@"marginBottom":@(bottom * scale.height),
21
22 @"marginLeft":@(left * scale.width),
23
24 @"marginRight":@(right * scale.width)};
25
26 [currentSegment updateStyleAtIndex:index styleAttributes:attributes];