{"feature_extractor_name":"scrolling_text_extractor","version":"v1","feature_extractor_id":"scrolling_text_extractor_v1","description":"Extracts scrolling/marquee text from video using phase-correlation band detection, panoramic stitching, and VLM OCR.\n\n**What it does:**\nDetects text that scrolls across the screen — horizontally (R-to-L / L-to-R tickers, banners, promotions) or vertically (credits, disclaimers, terms). No single frame shows the full text; this extractor reconstructs the complete string by stitching frames together like a panorama photograph.\n\n**Pipeline:**\n1. Sample video frames at configurable FPS\n2. Split frames into horizontal and vertical strips\n3. Phase-correlate consecutive frames to detect per-strip pixel shift\n4. Merge strips with consistent shift into scrolling bands\n5. Panoramic-stitch each band into one wide/tall image\n6. OCR the panorama via Gemini vision (VLM)\n7. Deduplicate repeated marquee loops\n\n**Use for:** Video ads with scrolling banners/tickers, news chyrons, scrolling disclaimers/T&Cs, credits sequences, live event info bars.\n\n**Not for:** Static text overlays (use multimodal_extractor with run_ocr), spoken content (use multimodal_extractor with run_transcription), animated text with non-linear motion (fade, scale, rotate).\n\n**Processing speed:** ~2-5x realtime depending on resolution and FPS.","icon":"scroll-text","category":"video","source":"builtin","type_mode":"type_specific","expected_input_types":{"video":"video"},"inference_type":"general","input_schema":{"description":"Input schema for the scrolling text extractor.\n\nAccepts a video file URL or S3 path. The video is analyzed frame-by-frame\nto detect and extract scrolling text overlays.\n\nRequirements:\n    - Video must be at least ~2 seconds long (3+ frames needed for correlation)\n    - Supports: MP4, MOV, AVI, MKV, WebM, FLV\n    - Recommended resolution: 480p–1080p (higher res = slower but more accurate OCR)\n    - Text must scroll at a roughly consistent speed for best results","examples":[{"description":"Video ad with scrolling banner","video":"s3://my-bucket/ads/summer-sale-30s.mp4"}],"properties":{"video":{"description":"URL or S3 path to a video file containing scrolling text. The extractor samples frames and uses phase correlation to detect which screen regions contain scrolling text, then stitches those regions into a panorama for OCR. Formats: MP4, MOV, AVI, MKV, WebM, FLV. Examples: 's3://bucket/ads/promo.mp4', 'https://cdn.example.com/video.mp4'","examples":["s3://my-bucket/ads/summer-sale-30s.mp4","https://storage.googleapis.com/my-videos/news-clip.mp4"],"title":"Video","type":"string"}},"required":["video"],"title":"ScrollingTextExtractorInput","type":"object"},"output_schema":{"description":"Output schema for the scrolling text extractor.\n\nOne document per source video. Contains the combined extracted text\nfrom all detected scrolling bands and per-band details. The text is\nstored as payload only — semantic search uses the text_extractor vector.\n\nOutput Structure:\n    - scrolling_text: Combined text from all bands (pipe-separated if multiple)\n    - scroll_bands: Array of per-band details (axis, direction, text)\n    - bands_detected: Number of scrolling bands found","examples":[{"bands_detected":1,"scroll_bands":[{"axis":"horizontal","direction":"right_to_left","shift_per_frame":-4.2,"text":"MEMORIAL DAY SALE — UP TO 50% OFF EVERYTHING"}],"scrolling_text":"MEMORIAL DAY SALE — UP TO 50% OFF EVERYTHING"}],"properties":{"scrolling_text":{"anyOf":[{"type":"string"},{"type":"null"}],"default":null,"description":"Full extracted scrolling text, combined from all detected bands. If multiple bands are found, their texts are joined with ' | '. Repeated marquee loops are automatically deduplicated.","title":"Scrolling Text"},"scroll_bands":{"anyOf":[{"items":{"additionalProperties":true,"type":"object"},"type":"array"},{"type":"null"}],"default":null,"description":"Per-band extraction details. Each entry contains: axis (horizontal/vertical), direction (right_to_left, etc.), shift_per_frame (px), and the extracted text for that band.","title":"Scroll Bands"},"bands_detected":{"anyOf":[{"type":"integer"},{"type":"null"}],"default":null,"description":"Number of scrolling text bands detected in the video.","title":"Bands Detected"}},"title":"ScrollingTextExtractorOutput","type":"object"},"parameter_schema":{"description":"Parameters for the scrolling text extractor.\n\nDetects and extracts scrolling/marquee text from video using computer vision\n(phase-correlation band detection + panoramic stitching) and VLM-based OCR.\n\n**When to Use**:\n    - Video ads with scrolling promotional banners or tickers\n    - News broadcasts with scrolling chyrons or tickers\n    - Videos with scrolling terms & conditions or disclaimers\n    - Social media content with horizontally scrolling text overlays\n    - Credits sequences in film/TV content\n    - Live event streams with scrolling info bars\n    - Any video where important text scrolls across the screen\n\n**When NOT to Use**:\n    - Static text overlays → use multimodal_extractor with run_ocr=True\n    - Spoken content → use multimodal_extractor with run_transcription=True\n    - Text documents/PDFs → use text_extractor\n    - Animated text that fades/scales (not linear scroll) → use multimodal_extractor\n\n**How It Works**:\n    1. Sample frames from video at configurable FPS\n    2. Split each frame into horizontal and vertical strips\n    3. Phase-correlate consecutive frames to measure per-strip pixel shift\n    4. Strips with consistent shift in one direction = scrolling band\n    5. Stitch the band across frames into a single wide/tall panorama image\n    6. OCR the panorama using a vision language model (Gemini)\n    7. Deduplicate repeated marquee loops (e.g. \"SALE • SALE • SALE •\" → \"SALE\")\n\n**Performance**:\n    - Processing speed: ~2-5x realtime (depends on video resolution and FPS)\n    - Accuracy: Best with consistent scroll speed; handles variable speed with degradation\n    - Minimum video length: ~2 seconds (needs 3+ frames for correlation)\n\n**Supported Scroll Directions**:\n    - Horizontal: Right-to-left (most common), Left-to-right\n    - Vertical: Bottom-to-top (credits), Top-to-bottom","examples":[{"description":"Standard video ad with scrolling banner","extractor_type":"scrolling_text_extractor","fps":5.0,"strip_height":40,"use_case":"Extract promotional text from video ad tickers"},{"description":"Fast-scrolling news ticker","extractor_type":"scrolling_text_extractor","fps":10.0,"min_shift_px":3.0,"strip_height":30,"use_case":"Capture rapidly scrolling chyron text from news broadcasts"},{"consistency_ratio":0.5,"description":"Credits / disclaimer scroll","extractor_type":"scrolling_text_extractor","fps":5.0,"min_shift_px":1.5,"strip_height":60,"use_case":"Extract vertically scrolling credits or legal disclaimers"}],"properties":{"extractor_type":{"const":"scrolling_text_extractor","default":"scrolling_text_extractor","description":"Discriminator field. Must be 'scrolling_text_extractor'.","title":"Extractor Type","type":"string"},"fps":{"default":5.0,"description":"Frame sampling rate for analysis. Higher values improve detection accuracy for fast-scrolling text but increase processing time. 5 FPS works well for most video ads and tickers.","maximum":30.0,"minimum":1.0,"title":"Fps","type":"number"},"strip_height":{"default":40,"description":"Height (in pixels) of each scanning strip used for phase correlation. Should roughly match the height of the scrolling text band. Smaller values detect narrower text bands; larger values are more robust but may miss thin tickers. 40px works for most standard video ads.","maximum":200,"minimum":10,"title":"Strip Height","type":"integer"},"min_shift_px":{"default":2.0,"description":"Minimum pixel shift per frame to consider a strip as 'scrolling'. Lower values detect slower-moving text; higher values filter out noise. 2.0px is a good default for 5 FPS sampling.","maximum":20.0,"minimum":0.5,"title":"Min Shift Px","type":"number"},"consistency_ratio":{"default":0.6,"description":"Fraction of frame pairs that must show consistent shift for a band to be classified as scrolling. 0.6 means 60% of frames must agree. Lower values detect intermittent scrolling; higher values reduce false positives.","maximum":1.0,"minimum":0.3,"title":"Consistency Ratio","type":"number"},"pad":{"default":8,"description":"Pixel padding above/below detected band when cropping for stitching.","maximum":50,"minimum":0,"title":"Pad","type":"integer"}},"title":"ScrollingTextExtractorParams","type":"object"},"supported_input_types":["video"],"max_inputs":{"video":1},"default_parameters":{},"costs":{"tier":3,"tier_label":"ADVANCED","rates":[{"unit":"minute","credits_per_unit":30,"description":"Video processing per minute (frame extraction + stitching + VLM OCR)"}]},"required_vector_indexes":null,"required_payload_indexes":[],"position_fields":[],"capabilities":["batch"],"example_usage":{"namespace":{"feature_extractors":[{"name":"scrolling_text_extractor","version":"v1"}]},"collection":{"feature_extractor":{"name":"scrolling_text_extractor","version":"v1","input_mappings":{"video":"<your_video_field>"},"parameters":{"fps":5.0,"strip_height":40,"min_shift_px":2.0,"consistency_ratio":0.6,"pad":8}}}}}