{"record":{"id":"afab5b15edb62ba2","repo":"TeamNewPipe/NewPipe","slug":"ttml-to-srt-conversion-failed","errorCode":null,"errorMessage":"TTML to SRT conversion failed","messagePattern":"TTML to SRT conversion failed","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"app/src/main/java/us/shandian/giga/postprocessing/TtmlConverter.java","lineNumber":37,"sourceCode":"    }\n\n    @Override\n    int process(SharpStream out, SharpStream... sources) throws IOException {\n        // check if the subtitle is already in srt and copy, this should never happen\n        String format = getArgumentAt(0, null);\n        boolean ignoreEmptyFrames = getArgumentAt(1, \"true\").equals(\"true\");\n\n        if (format == null || format.equals(\"ttml\")) {\n            SrtFromTtmlWriter writer = new SrtFromTtmlWriter(out, ignoreEmptyFrames);\n\n            try {\n                writer.build(sources[0]);\n            } catch (IOException err) {\n                Log.e(TAG, \"subtitle conversion failed due to I/O error\", err);\n                throw err;\n            } catch (Exception err) {\n                Log.e(TAG, \"subtitle conversion failed\", err);\n                throw new IOException(\"TTML to SRT conversion failed\", err);\n            }\n\n            return OK_RESULT;\n        } else if (format.equals(\"srt\")) {\n            byte[] buffer = new byte[8 * 1024];\n            int read;\n            while ((read = sources[0].read(buffer)) > 0) {\n                out.write(buffer, 0, read);\n            }\n            return OK_RESULT;\n        }\n\n        throw new UnsupportedOperationException(\"Can't convert this subtitle, unimplemented format: \" + format);\n    }\n\n}\n","sourceCodeStart":19,"sourceCodeEnd":54,"githubUrl":"https://github.com/TeamNewPipe/NewPipe/blob/9e8be091560a69f35d44bd252eb00bc7911c977b/app/src/main/java/us/shandian/giga/postprocessing/TtmlConverter.java#L19-L54","documentation":"Thrown by TtmlConverter when SrtFromTtmlWriter.build() throws a non-IOException exception (IOException is re-thrown directly). The catch-all Exception handler wraps the cause in an IOException with the message 'TTML to SRT conversion failed'. This happens during subtitle post-processing when the TTML source is malformed XML, has unexpected structure, or the writer hits a parse/number-format error it does not handle internally.","triggerScenarios":"TtmlConverter.process calls writer.build(sources[0]); inside build, an unchecked exception (XmlPullParserException, NumberFormatException, IllegalStateException, NullPointerException, etc.) escapes; the catch-Exception block wraps it. Caused by a TTML file that is not well-formed XML, has missing cue attributes, malformed timestamps, or unexpected element nesting.","commonSituations":"Subtitle source is truncated/malformed XML; a TTML variant with attributes the parser does not expect; timestamp values in a non-standard format causing NumberFormatException; empty or whitespace-only TTML documents; a provider serving HTML or an error page instead of TTML.","solutions":["Pre-validate the TTML source is well-formed XML before conversion (parse with a forgiving parser, check root element is <tt>).","Inspect the wrapped cause (IOException.getCause()) to identify the specific parse failure and fix that input.","Handle the conversion failure gracefully and fall back to the original subtitle file or no subtitles.","Update the SrtFromTtmlWriter if a specific TTML structure is consistently unhandled."],"exampleFix":"// before — let the wrapped exception propagate\ntry {\n    writer.build(sources[0]);\n} catch (IOException err) {\n    Log.e(TAG, \"subtitle conversion failed due to I/O error\", err);\n    throw err;\n}\n\n// after — inspect cause and degrade gracefully\ntry {\n    writer.build(sources[0]);\n} catch (IOException err) {\n    Throwable cause = err.getCause();\n    Log.e(TAG, \"TTML conversion failed: \" + (cause != null ? cause.getMessage() : \"unknown\"), err);\n    // fall back: copy original TTML through if conversion is impossible\n}","handlingStrategy":"try-catch","validationCode":"// Pre-validate the TTML source is well-formed XML before conversion:\nXmlPullParserFactory factory = XmlPullParserFactory.newInstance();\nXmlPullParser parser = factory.newPullParser();\nparser.setInput(new InputStreamReader(sources[0]));\ntry {\n    parser.next(); // will throw if not well-formed\n} catch (XmlPullParserException e) {\n    throw new IOException(\"TTML source is not well-formed XML\", e);\n}\nsources[0].seek(0); // rewind for the writer","typeGuard":null,"tryCatchPattern":"try {\n    writer.build(sources[0]);\n} catch (IOException err) {\n    if (\"TTML to SRT conversion failed\".equals(err.getMessage())) {\n        // unwrap cause for diagnostics, then fall back to raw passthrough\n        Log.e(TAG, \"TTML parse error: \" + err.getCause());\n        copyRawTtml(sources[0], out);\n    } else throw err;\n}","preventionTips":["Validate the TTML document is well-formed XML before passing to the converter.","Inspect the wrapped cause (IOException.getCause()) to find the real parse failure.","Provide a fallback (raw subtitle passthrough) when conversion fails."],"tags":["subtitle","ttml","srt","postprocessing","xml-parsing"],"backgroundTag":null,"analyzedSha":"9e8be091560a69f35d44bd252eb00bc7911c977b","analyzedAt":"2026-08-14T00:11:33.519Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}