📄 mediaplayerprivateqtkit.mm
字号:
m_player->timeChanged();}void MediaPlayerPrivate::didEnd(){ m_endPointTimer.stop(); m_startedPlaying = false;#if DRAW_FRAME_RATE m_timeStoppedPlaying = [NSDate timeIntervalSinceReferenceDate];#endif updateStates(); m_player->timeChanged();}void MediaPlayerPrivate::setSize(const IntSize& size) { if (!m_qtMovieView) return; m_rect.setSize(size); if (m_player->inMediaDocument()) // We need the QTMovieView to be placed in the proper location for document mode. [m_qtMovieView.get() setFrame:m_rect]; else { // We don't really need the QTMovieView in any specific location so let's just get it out of the way // where it won't intercept events or try to bring up the context menu. IntRect farAwayButCorrectSize(m_rect); farAwayButCorrectSize.move(-1000000, -1000000); [m_qtMovieView.get() setFrame:farAwayButCorrectSize]; } }void MediaPlayerPrivate::setVisible(bool b){ if (m_visible != b) { m_visible = b; if (b) { if (m_networkState >= MediaPlayer::LoadedMetaData) setUpVideoRendering(); } else tearDownVideoRendering(); }}void MediaPlayerPrivate::repaint(){#if DRAW_FRAME_RATE if (m_startedPlaying) { m_frameCountWhilePlaying++; // to eliminate preroll costs from our calculation, // our frame rate calculation excludes the first frame drawn after playback starts if (1==m_frameCountWhilePlaying) m_timeStartedPlaying = [NSDate timeIntervalSinceReferenceDate]; }#endif m_player->repaint();}void MediaPlayerPrivate::paint(GraphicsContext* context, const IntRect& r){ if (context->paintingDisabled()) return; NSView *view = m_qtMovieView.get(); id qtVideoRenderer = m_qtVideoRenderer.get(); if (!view && !qtVideoRenderer) return; [m_objcObserver.get() setDelayCallbacks:YES]; BEGIN_BLOCK_OBJC_EXCEPTIONS; context->save(); context->translate(r.x(), r.y() + r.height()); context->scale(FloatSize(1.0f, -1.0f)); context->setImageInterpolationQuality(InterpolationLow); IntRect paintRect(IntPoint(0, 0), IntSize(r.width(), r.height())); #ifdef BUILDING_ON_TIGER AutodrainedPool pool;#endif NSGraphicsContext* newContext = [NSGraphicsContext graphicsContextWithGraphicsPort:context->platformContext() flipped:NO]; // draw the current video frame if (qtVideoRenderer) { [NSGraphicsContext saveGraphicsState]; [NSGraphicsContext setCurrentContext:newContext]; [(id<WebKitVideoRenderingDetails>)qtVideoRenderer drawInRect:paintRect]; [NSGraphicsContext restoreGraphicsState]; } else { if (m_player->inMediaDocument() && r != m_rect) { // the QTMovieView needs to be placed in the proper location for document mode m_rect = r; [view setFrame:m_rect]; } [view displayRectIgnoringOpacity:paintRect inContext:newContext]; }#if DRAW_FRAME_RATE // Draw the frame rate only after having played more than 10 frames. if (m_frameCountWhilePlaying > 10) { Frame* frame = m_player->frameView() ? m_player->frameView()->frame() : NULL; Document* document = frame ? frame->document() : NULL; RenderObject* renderer = document ? document->renderer() : NULL; RenderStyle* styleToUse = renderer ? renderer->style() : NULL; if (styleToUse) { double frameRate = (m_frameCountWhilePlaying - 1) / ( m_startedPlaying ? ([NSDate timeIntervalSinceReferenceDate] - m_timeStartedPlaying) : (m_timeStoppedPlaying - m_timeStartedPlaying) ); String text = String::format("%1.2f", frameRate); TextRun textRun(text.characters(), text.length()); const Color color(255, 0, 0); context->scale(FloatSize(1.0f, -1.0f)); context->setFont(styleToUse->font()); context->setStrokeColor(color); context->setStrokeStyle(SolidStroke); context->setStrokeThickness(1.0f); context->setFillColor(color); context->drawText(textRun, IntPoint(2, -3)); } }#endif context->restore(); END_BLOCK_OBJC_EXCEPTIONS; [m_objcObserver.get() setDelayCallbacks:NO];}static HashSet<String> mimeTypeCache(){ DEFINE_STATIC_LOCAL(HashSet<String>, cache, ()); static bool typeListInitialized = false; if (!typeListInitialized) { NSArray* fileTypes = [QTMovie movieFileTypes:QTIncludeCommonTypes]; int count = [fileTypes count]; for (int n = 0; n < count; n++) { CFStringRef ext = reinterpret_cast<CFStringRef>([fileTypes objectAtIndex:n]); RetainPtr<CFStringRef> uti(AdoptCF, UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, ext, NULL)); if (!uti) continue; RetainPtr<CFStringRef> mime(AdoptCF, UTTypeCopyPreferredTagWithClass(uti.get(), kUTTagClassMIMEType)); if (!mime) continue; cache.add(mime.get()); } typeListInitialized = true; } return cache;} void MediaPlayerPrivate::getSupportedTypes(HashSet<String>& types){ types = mimeTypeCache();} MediaPlayer::SupportsType MediaPlayerPrivate::supportsType(const String& type, const String& codecs){ // only return "IsSupported" if there is no codecs parameter for now as there is no way to ask QT if it supports an // extended MIME type yet return mimeTypeCache().contains(type) ? (codecs && !codecs.isEmpty() ? MediaPlayer::MayBeSupported : MediaPlayer::IsSupported) : MediaPlayer::IsNotSupported;}bool MediaPlayerPrivate::isAvailable(){#ifdef BUILDING_ON_TIGER SInt32 version; OSErr result; result = Gestalt(gestaltQuickTime, &version); if (result != noErr) { LOG_ERROR("No QuickTime available. Disabling <video> and <audio> support."); return false; } if (version < minimumQuickTimeVersion) { LOG_ERROR("QuickTime version %x detected, at least %x required. Disabling <video> and <audio> support.", version, minimumQuickTimeVersion); return false; } return true;#else // On 10.5 and higher, QuickTime will always be new enough for <video> and <audio> support, so we just check that the framework can be loaded. return QTKitLibrary();#endif} void MediaPlayerPrivate::disableUnsupportedTracks(unsigned& enabledTrackCount){ if (!m_qtMovie) { enabledTrackCount = 0; return; } static HashSet<String>* allowedTrackTypes = 0; if (!allowedTrackTypes) { allowedTrackTypes = new HashSet<String>; allowedTrackTypes->add(QTMediaTypeVideo); allowedTrackTypes->add(QTMediaTypeSound); allowedTrackTypes->add(QTMediaTypeText); allowedTrackTypes->add(QTMediaTypeBase); allowedTrackTypes->add(QTMediaTypeMPEG); allowedTrackTypes->add("clcp"); allowedTrackTypes->add("sbtl"); } NSArray *tracks = [m_qtMovie.get() tracks]; unsigned trackCount = [tracks count]; enabledTrackCount = trackCount; for (unsigned trackIndex = 0; trackIndex < trackCount; trackIndex++) { // Grab the track at the current index. If there isn't one there, then // we can move onto the next one. QTTrack *track = [tracks objectAtIndex:trackIndex]; if (!track) continue; // Check to see if the track is disabled already, we should move along. // We don't need to re-disable it. if (![track isEnabled]) continue; // Grab the track's media. We're going to check to see if we need to // disable the tracks. They could be unsupported. QTMedia *trackMedia = [track media]; if (!trackMedia) continue; // Grab the media type for this track. NSString *mediaType = [trackMedia attributeForKey:QTMediaTypeAttribute]; if (!mediaType) continue; // Test whether the media type is in our white list. if (!allowedTrackTypes->contains(mediaType)) { // If this track type is not allowed, then we need to disable it. [track setEnabled:NO]; --enabledTrackCount; } // Disable chapter tracks. These are most likely to lead to trouble, as // they will be composited under the video tracks, forcing QT to do extra // work. QTTrack *chapterTrack = [track performSelector:@selector(chapterlist)]; if (!chapterTrack) continue; // Try to grab the media for the track. QTMedia *chapterMedia = [chapterTrack media]; if (!chapterMedia) continue; // Grab the media type for this track. id chapterMediaType = [chapterMedia attributeForKey:QTMediaTypeAttribute]; if (!chapterMediaType) continue; // Check to see if the track is a video track. We don't care about // other non-video tracks. if (![chapterMediaType isEqual:QTMediaTypeVideo]) continue; // Check to see if the track is already disabled. If it is, we // should move along. if (![chapterTrack isEnabled]) continue; // Disable the evil, evil track. [chapterTrack setEnabled:NO]; --enabledTrackCount; }}}@implementation WebCoreMovieObserver- (id)initWithCallback:(MediaPlayerPrivate*)callback{ m_callback = callback; return [super init];}- (void)disconnect{ [NSObject cancelPreviousPerformRequestsWithTarget:self]; m_callback = 0;}-(NSMenu*)menuForEventDelegate:(NSEvent*)theEvent{ // Get the contextual menu from the QTMovieView's superview, the frame view return [[m_view superview] menuForEvent:theEvent];}-(void)setView:(NSView*)view{ m_view = view;}-(void)repaint{ if (m_delayCallbacks) [self performSelector:_cmd withObject:nil afterDelay:0.]; else if (m_callback) m_callback->repaint();}- (void)loadStateChanged:(NSNotification *)unusedNotification{ UNUSED_PARAM(unusedNotification); if (m_delayCallbacks) [self performSelector:_cmd withObject:nil afterDelay:0]; else m_callback->loadStateChanged();}- (void)rateChanged:(NSNotification *)unusedNotification{ UNUSED_PARAM(unusedNotification); if (m_delayCallbacks) [self performSelector:_cmd withObject:nil afterDelay:0]; else m_callback->rateChanged();}- (void)sizeChanged:(NSNotification *)unusedNotification{ UNUSED_PARAM(unusedNotification); if (m_delayCallbacks) [self performSelector:_cmd withObject:nil afterDelay:0]; else m_callback->sizeChanged();}- (void)timeChanged:(NSNotification *)unusedNotification{ UNUSED_PARAM(unusedNotification); if (m_delayCallbacks) [self performSelector:_cmd withObject:nil afterDelay:0]; else m_callback->timeChanged();}- (void)didEnd:(NSNotification *)unusedNotification{ UNUSED_PARAM(unusedNotification); if (m_delayCallbacks) [self performSelector:_cmd withObject:nil afterDelay:0]; else m_callback->didEnd();}- (void)newImageAvailable:(NSNotification *)unusedNotification{ UNUSED_PARAM(unusedNotification); [self repaint];}- (void)setDelayCallbacks:(BOOL)shouldDelay{ m_delayCallbacks = shouldDelay;}@end#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -